2014-11-03 5 views
5

मेरे पास एक ऐसा एप्लिकेशन है जिसका काम कई अन्य प्रक्रियाओं को शुरू करना और बंद करना है।क्यूटी प्रक्रिया समाप्त करें: विंडोज टास्क मैनेजर क्या कर रहा है कि मैं नहीं हूं?

समस्या यह है कि क्यूटी अनुप्रयोग स्पष्ट रूप से बंद नहीं होते हैं। क्यूटी खिड़की बंद हो जाती है, लेकिन प्रक्रिया अभी भी पृष्ठभूमि में चलती है, जब तक कि टर्मिनेट प्रोसेस() को कॉल नहीं किया जाता है और फिर क्यूटी ऐप सफाई के बिना निकलता है।

मैं माइक्रोसॉफ्ट द्वारा उल्लिखित this method का उपयोग कर रहा हूं। यहां तक ​​कि Qt source प्रक्रिया को समाप्त करने के लिए उस विधि का उपयोग करता है, सिवाय इसके कि वे मुख्य थ्रेड पर WM_CLOSE पोस्ट भी करते हैं। मैंने यह भी जोड़ा है कि मेरे आवेदन में भी है लेकिन यह अभी भी प्रक्रिया को छोड़कर विंडो बंद कर देता है।

मुझे जो दिलचस्प लगता है वह यह है कि यदि मैं "कार्य कार्य" ("अंत प्रक्रिया" नहीं) के लिए विंडोज टास्क मैनेजर का उपयोग करता हूं, तो विंडो बंद हो जाती है और प्रक्रिया भी समाप्त होती है, इसलिए मुझे पता है कि यह संभव है। यदि मैं जासूस ++ का उपयोग करता हूं तो मैं देख सकता हूं कि मुख्य विंडो और मुख्य धागा दोनों कार्य प्रबंधक और मेरे अनुप्रयोग से WM_CLOSE संदेश प्राप्त करते हैं, लेकिन केवल कार्य प्रबंधक का उपयोग करके संदेश WM_DESTROY, WM_NCDESTROY आदि पर जारी रहते हैं और प्रक्रिया समाप्त होने के साथ समाप्त होते हैं । यह समस्या केवल क्यूटी अनुप्रयोगों के साथ होती है। Win32/MFC आदि अनुप्रयोगों को मेरे आवेदन का उपयोग कर साफ से समाप्त कर दिया।

आपको क्यूटी ऐप्स को साफ-सफाई कैसे बंद करना है (मान लें कि क्यूटी ऐप स्रोत उपलब्ध नहीं है)?

-------- संपादित करें --------

यहां कुछ नमूना कोड है कि समस्या को पुन: होगा। कम से कम, मुझे यह जानने में दिलचस्पी होगी कि क्या अन्य लोग वही समस्या देखते हैं जो मैं देख रहा हूं।

नमूना कोड सीएमके (download here) शुरू करता है, लेकिन किसी भी क्यूटी ऐप को करना चाहिए।

#include <Windows.h> 
#include <iostream> 

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* processName = "C:\\Program Files (x86)\\CMake\\bin\\cmake-gui.exe"; 
    //char* processName = "C:\\Windows\\Notepad.exe"; 

    std::cout << "Creating process \"" << processName << "\"" << std::endl; 

    STARTUPINFO si = {0}; 
    si.cb = sizeof(STARTUPINFO); 
    PROCESS_INFORMATION pi = {0}; 

    BOOL success = CreateProcess(processName, 
           "", 
           NULL, 
           NULL, 
           FALSE, 
           0, 
           NULL, 
           NULL, 
           &si, 
           &pi); 

    if (success) 
    { 
    std::cout << "Press any key to cleanly terminate process..." << std::endl; 
    std::cin.get(); 

    std::cout << "Cleanly terminating process..." << std::endl; 

    EnumWindows(TerminateAppEnum, (LPARAM)pi.dwProcessId); 
    PostThreadMessage(pi.dwThreadId, WM_CLOSE, 0, 0); 

    if (WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0) 
    { 
     std::cout << "Success! The process has terminated" << std::endl; 
    } 
    else 
    { 
     std::cout << "Failed! The process is still running" << std::endl; 
    } 
    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 
    } 
    else 
    { 
    std::cout << "Unable to start process (Error " << GetLastError() << ")" << std::endl; 
    } 
    std::cout << "Press any key to exit..." << std::endl; 
    std::cin.get(); 

    return 0; 
} 

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid) 
{ 
    DWORD dwPID; 
    GetWindowThreadProcessId(hwnd, &dwPID); 

    if (dwPID == (DWORD)pid) 
    { 
    PostMessage(hwnd, WM_CLOSE, 0, 0); 
    } 

    return TRUE; 
} 
+2

क्यूटी सामान्य रूप से जानता है, जब यह बाहर निकलने के लिए जरूरत है, और को छोड़कर अगर डेवलपर में गड़बड़ है, जो आप पर नज़र डालकर देख सकते हैं, इसलिए सफाई से करता है (अनुपलब्ध) स्रोत कोड ... – SirDarius

+0

@ सरदार: यह मेरी विचार प्रक्रिया भी होगी, लेकिन इस कार्यक्रम का प्रबंधन करने वाले सभी अनुप्रयोगों में से केवल क्यूटी के पास यह समस्या है (3 कुल), और वे सभी अलग-अलग लेखकों द्वारा हैं। संयोग? इसके अलावा, कार्य प्रबंधक उन्हें साफ कर सकते हैं, लेकिन कैसे ..? – parrowdice

+0

मैं आपको सुझाव दे सकता हूं कि आप तीसरे पक्ष के ओपन सोर्स क्यूटी प्रोग्राम जैसे कि सेमेक गुई जैसे कि आप डीबग कर सकते हैं और देखें कि इसे कैसे लागू किया गया है – SirDarius

उत्तर

2

ठीक है, इसे हल किया गया।

समस्या इस तथ्य से आती है कि क्यूटी एक शीर्ष-स्तरीय विंडो बनाता है - QEventDispatcher विंडो। माइक्रोसॉफ्ट द्वारा उल्लिखित प्रक्रिया के बाद, इस विंडो को एक WM_CLOSE संदेश मिलता है, जो उस विंडो और उसके धागे को बंद कर देता है। उसके बाद, जब एप्लिकेशन की मुख्य विंडो बंद हो जाती है, तो कोई साफ-सफाई नहीं की जाती है और प्रक्रिया सिस्टम मेमोरी में बनी हुई है।

दिलचस्प बात यह है कि कार्य प्रबंधक का उपयोग करके, QEventDispatcher नहीं एक WM_CLOSE संदेश इतना सक्रिय रहता है जब मुख्य विंडो एक WM_CLOSE संदेश प्रक्रिया सफाई से बाहर निकल जाता है GES प्राप्त करता है, और इसलिए है। मैं केवल यह मान सकता हूं कि IsWindowVisible जैसे कुछ को कॉल प्रबंधक में EnumWindowsProc callback में उपयोग किया जा रहा है, उनके documentation के विपरीत। हालांकि एक दशक पहले उस दस्तावेज़ीकरण की आखिरी समीक्षा की गई थी!

IsWindowVisible को कॉल में जोड़ना प्रोग्राम को सभी क्यूटी ऐप्स के साथ काम कर रहा है, और अन्य गैर-क्यूटी ऐप्स भी इस बदलाव के साथ काम करने में खुश रहते हैं। पूर्णता के लिए, मैं अद्यतन नमूना कोड शामिल किया है:

#include <Windows.h> 
#include <iostream> 

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid); 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* processName = "C:\\Program Files (x86)\\CMake\\bin\\cmake-gui.exe"; 
    //char* processName = "C:\\Windows\\Notepad.exe"; 

    std::cout << "Creating process \"" << processName << "\"" << std::endl; 

    STARTUPINFO si = {0}; 
    si.cb = sizeof(STARTUPINFO); 
    PROCESS_INFORMATION pi = {0}; 

    BOOL success = CreateProcess(processName, 
           "", 
           NULL, 
           NULL, 
           FALSE, 
           0, 
           NULL, 
           NULL, 
           &si, 
           &pi); 

    if (success) 
    { 
    std::cout << "Press any key to cleanly terminate process..." << std::endl; 
    std::cin.get(); 

    std::cout << "Cleanly terminating process..." << std::endl; 

    EnumWindows(TerminateAppEnum, (LPARAM)pi.dwProcessId); 

    if (WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0) 
    { 
     std::cout << "Success! The process has terminated" << std::endl; 
    } 
    else 
    { 
     std::cout << "Failed! The process is still running" << std::endl; 
    } 
    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 
    } 
    else 
    { 
    std::cout << "Unable to start process (Error " << GetLastError() << ")" << std::endl; 
    } 
    std::cout << "Press any key to exit..." << std::endl; 
    std::cin.get(); 

    return 0; 
} 

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid) 
{ 
    DWORD dwPID; 
    GetWindowThreadProcessId(hwnd, &dwPID); 

    if (dwPID == (DWORD)pid) 
    { 
    if (IsWindowVisible(hwnd)) 
    { 
     PostMessage(hwnd, WM_CLOSE, 0, 0); 
    } 
    } 

    return TRUE; 
} 
संबंधित मुद्दे