使用sendmessage将wm_close发送到另一个进程

发布于 2024-10-25 18:55:14 字数 832 浏览 6 评论 0原文

我想将 wm_close 发送到另一个进程,我想用它安全地结束该进程。

int _tmain(int argc, _TCHAR* argv[])
{

    DWORD SetOfPID;
    SetOfPID = GetProcId(_T("abc.exe"));  //this will return pid
    HANDLE h = OpenProcess(PROCESS_ALL_ACCESS,false, SetOfPID);

    HWND hwnd = ::GetTopWindow(NULL);
    while(hwnd)
    {
        DWORD pid;
        DWORD dwThreadId = ::GetWindowThreadProcessId(hwnd, &pid);
         if(pid == SetOfPID)
         {    
              break;
         }
         hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
    }
    //DestroyWindow(hwnd);
    bool temp = IsWindow(hwnd); **//this gives true**
    LRESULT res = ::SendMessage(hwnd, WM_CLOSE, NULL, NULL);
    DWORD err = GetLastError(); **//this gives 6**
    CloseHandle(hwnd);
    CloseHandle(h);
    return 0;
}

这段代码看起来不错,但目标进程没有终止,有人可以帮助我吗?

I want to send wm_close to another process, with which i want end that process safely.

int _tmain(int argc, _TCHAR* argv[])
{

    DWORD SetOfPID;
    SetOfPID = GetProcId(_T("abc.exe"));  //this will return pid
    HANDLE h = OpenProcess(PROCESS_ALL_ACCESS,false, SetOfPID);

    HWND hwnd = ::GetTopWindow(NULL);
    while(hwnd)
    {
        DWORD pid;
        DWORD dwThreadId = ::GetWindowThreadProcessId(hwnd, &pid);
         if(pid == SetOfPID)
         {    
              break;
         }
         hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
    }
    //DestroyWindow(hwnd);
    bool temp = IsWindow(hwnd); **//this gives true**
    LRESULT res = ::SendMessage(hwnd, WM_CLOSE, NULL, NULL);
    DWORD err = GetLastError(); **//this gives 6**
    CloseHandle(hwnd);
    CloseHandle(h);
    return 0;
}

this piece of code looks good, but the target process doesn't terminate, can somebody help me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

仙气飘飘 2024-11-01 18:55:14

我将尝试按以下顺序关闭(进程)窗口:

  1. WM_CLOSE

  2. WM_QUIT

  3. WM_DESTROY

  4. TerminateProcess()。

这只是我的看法,因为我正在处理(禁用)窗口的 WM_CLOSE ,并且很难区分用户关闭和另一个主任务发送的关闭消息。 WM_QUIT 似乎无需使用我自己的自定义 WM_APP_CLOSE 即可解决我的问题。 TerminateProcess 是不惜一切代价避免不干净退出的最后手段(它可能会留下句柄(例如 COM 等)和内存等未释放的)。

I would attempt to close a (Process with) Window(s) in the following order:

  1. WM_CLOSE

  2. WM_QUIT

  3. WM_DESTROY

  4. TerminateProcess().

Just my take as I am handling (disabling) WM_CLOSE for a Window and having difficulty distinguishing between User Close and close messages send by another master task. WM_QUIT seems to resolve my problem without using a custom WM_APP_CLOSE of my own. TerminateProcess is very much a last resort unclean exit to be avoided at all costs (it may leave handles (e.g. COM etc) and memory etc unfreed).

亢潮 2024-11-01 18:55:14

您确定您找到的窗口是正确的吗?您可以使用 Spy++ 轻松检查。而且,在搜索窗口时,我认为使用EnumWindows更好。我不确定你的方法是否正确。

Are you sure that the window you are finding is the correct one? You can check easily with Spy++. Moreover, when searching for a window, I think it's better to use EnumWindows. I'm not sure your method is correct.

゛清羽墨安 2024-11-01 18:55:14

如果应用程序不处理 WM_CLOSE,则 DefWindowProc 应该处理此问题(通过正常关闭应用程序),但是如果应用程序正在处理 WM_CLOSE,则它可以选择忽略它。尝试发送 WM_DESTROY 和 WM_NCDESTROY 消息。

If the application does not process WM_CLOSE the DefWindowProc should handle this (by gracefully closing the application), however if the application is handling WM_CLOSE then it simply can choose to ignore it. Try sending the WM_DESTROY and WM_NCDESTROY messagees instead.

你的背包 2024-11-01 18:55:14

我发现了一个从 Tonto 使用不同的方法来查找要发送到的窗口。

它使用 EnumWindows() 来走过窗户。当它找到具有匹配 PID 的信息时,它会发送该消息。

这是一个稍作修改的版本(相同,但发送 WM_CLOSE):

#include <windows.h>
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    DWORD processId;
    GetWindowThreadProcessId(hwnd, &processId);

    if(lParam == processId)
        PostMessage(hwnd, WM_CLOSE, 0, 0);
    return TRUE;
}

int main(int argc, char *argv[])
{
    STARTUPINFO         siInfo;
    PROCESS_INFORMATION piInfo;
 
    ZeroMemory(&siInfo, sizeof(siInfo));
    ZeroMemory(&piInfo, sizeof(piInfo));
 
    CreateProcess
        ("C:\\WINDOWS\\Notepad.exe", "", 0, 0, 
        FALSE, CREATE_DEFAULT_ERROR_MODE, 0, 0, 
        &siInfo, &piInfo);
 
    WaitForSingleObject(piInfo.hProcess, 1000);
    EnumWindows(&EnumWindowsProc, piInfo.dwProcessId);
    return 0;
}

这将启动 C:\WINDOWS\Notepad.exe 等待一秒钟,然后发送 WM_CLOSE。

这打开了记事本,然后将其关闭。当我用我的程序尝试它时,它也有效,所以我认为您在找到正确的窗口来发送消息时遇到问题。

注意此示例中没有错误检查。

I found an example of sending messages to a different processes window from Tonto that uses a different method of finding the window to send to.

It uses EnumWindows() to walk over the windows. When it finds the one with the matching PID it sends the message.

Here is a slightly modified version (the same but sends a sends the WM_CLOSE):

#include <windows.h>
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    DWORD processId;
    GetWindowThreadProcessId(hwnd, &processId);

    if(lParam == processId)
        PostMessage(hwnd, WM_CLOSE, 0, 0);
    return TRUE;
}

int main(int argc, char *argv[])
{
    STARTUPINFO         siInfo;
    PROCESS_INFORMATION piInfo;
 
    ZeroMemory(&siInfo, sizeof(siInfo));
    ZeroMemory(&piInfo, sizeof(piInfo));
 
    CreateProcess
        ("C:\\WINDOWS\\Notepad.exe", "", 0, 0, 
        FALSE, CREATE_DEFAULT_ERROR_MODE, 0, 0, 
        &siInfo, &piInfo);
 
    WaitForSingleObject(piInfo.hProcess, 1000);
    EnumWindows(&EnumWindowsProc, piInfo.dwProcessId);
    return 0;
}

This starts C:\WINDOWS\Notepad.exe waits a second and then sends the WM_CLOSE.

This opened notepad and then closed it. When I tried it with my program instead it also worked, so I think you are having problems find the right window to send the message to.

NOTE that there is no error checking in this example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文