windows 下在进程中使用createprocess创建一个窗口进程,并获取这个窗口HWND句柄

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows 下在进程中使用createprocess创建一个窗口进程,并获取这个窗口HWND句柄相关的知识,希望对你有一定的参考价值。

windows 下在一个进程中使用createprocess创建一个窗口进程,并获取这个窗口的HWND句柄

C++使用createprocess创建一个窗口进程,并获取这个窗口的HWND句柄。

主要思路是:

  1. 定义getDwProcessId函数,用于监听创建子窗口的活动。
  2. 定义EnumWindowsProcGetWndTitle回调函数,用于捕获子窗口句柄。
  3. 把捕获的句柄赋值给全局变量,用于主函数执行子窗口操作。

图例如下:

技术图片

示例如下:

  1. 程序入口点代码

    ```c++
    //zhaoanan 
    #pragma warning (disable : 4786)
    #include "stdafx.h"
    #include <stdlib.h>
    #include <winsock2.h>
    #include <iostream>
    #include <vector>
    #include <string>
    #include <fstream>
    #include <stdio.h>
    #include <windows.h>
    #include "RemoteCompileSFunc.h"
    
    #pragma comment(lib, "Kernel32.lib")
    using namespace std;
    
    #define RECEIVE_BUFFER_LEN 50
    
    #pragma comment(lib,"ws2_32.lib")
    
    void Build80Zc(const string& sExe, const string& sPath, const string& sCmd);
    BOOL CALLBACK EnumWindowsProcGetWndTitle(HWND hWnd, LPARAM lParam);
    DWORD getDwProcessId(DWORD g_dwProcessId);
    HWND g_hWnd = NULL;
    int main(int argc, char* argv[])
    {
       //执行make clean ab命令
       Build80Zc("C:\WindRiver3\wrenv.exe -p vxworks-cert-6.6.3.1", "cd C:\src\workspace\FAO_ZC_VXW_AB_TEST\cert", "make clean >> C:\src\workspace\FAO_ZC_VXW_AB_TEST\compile.txt");
       //执行make all ab命令
       Build80Zc("C:\WindRiver3\wrenv.exe -p vxworks-cert-6.6.3.1", "cd C:\src\workspace\FAO_ZC_VXW_AB_TEST\cert", "make all >> C:\src\workspace\FAO_ZC_VXW_AB_TEST\compile.txt");
       //执行make clean c命令
       Build80Zc("C:\WindRiver\wrenv.exe -p vxworks-6.9","cd C:\src\workspace\dtsApp\SIMNTdiab_SMP","make clean>>C:\src\workspace\dtsApp\compile.txt");
       //执行make all c命令
    Build80Zc("C:\WindRiver\wrenv.exe -p vxworks-6.9","cd C:\src\workspace\dtsApp\SIMNTdiab_SMP","make all>>C:\src\workspace\dtsApp\compile.txt");
       return 0;
    }
    
    BOOL CALLBACK EnumWindowsProcGetWndTitle(HWND hWnd, LPARAM lParam)
    {
    DWORD ProcID = 0;
    GetWindowThreadProcessId(hWnd, &ProcID);
    cout << "传入窗口的进程id:" << lParam << "当前窗口的进程id:" << ProcID << endl;
    cout << "当前窗口句柄:" << hWnd << endl;
    if (ProcID == lParam)//如果窗口的processid等于你的ID
    {
        HWND pWnd = GetParent(hWnd);
        cout << "第一父窗口句柄:" << pWnd << endl;
        while (GetParent(pWnd) != NULL)//得到父窗口的句柄
        {
            pWnd = GetParent(pWnd);
            cout << "父窗口句柄:" << pWnd << endl;
        }
        if (pWnd != NULL) 
        {
            g_hWnd = pWnd;
        } else 
        {
            g_hWnd = hWnd;
        }
        cout << "最终父窗口句柄:" << g_hWnd << endl;
        //ok ?pWnd 就是主窗口了。
        return FALSE;
    }
    return TRUE;
    }
    
    DWORD getDwProcessId(DWORD g_dwProcessId)
    {
    int nNumberDely = 1000;
    // 等待窗口动行起,获取到窗口HWND
    while(EnumWindows(EnumWindowsProcGetWndTitle,g_dwProcessId) && nNumberDely>0 )
    {
        nNumberDely--;
    }
    return g_dwProcessId;
    }
    
    void Build80Zc(const string& sExe, const string& sPath, const string& sCmd)
    {
    string::size_type idx;
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;
    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));
    idx = sPath.find("FAO_ZC_VXW_AB_TEST");
    if (idx == string::npos){
        CreateProcess(NULL, "C:\WindRiver\wrenv.exe -p vxworks-6.9", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        cout << "打开C机编译器" << endl;
    }
    else{
        CreateProcess(NULL, "C:\WindRiver3\wrenv.exe -p vxworks-cert-6.6.3.1", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
        cout << "打开AB机编译器" << endl;
    }
    Sleep(1000);
    DWORD g_dwProcessId = pi.dwProcessId;
    DWORD dwProcessId = getDwProcessId(g_dwProcessId);
       //查找当前窗口句柄需要一定的枚举时间,经过测试5s之内能枚举完成
    Sleep(5000);
    char* buf = (char*)sPath.c_str();
    int i;
    for (i = 0; i < strlen(buf); i++)
    {
        ::SendMessage(g_hWnd, WM_IME_CHAR, buf[i], 0);
    }
    ::SendMessage(g_hWnd, WM_IME_CHAR, 13, 0);
    Sleep(1000);
    buf = (char*)sCmd.c_str();
    for (i = 0; i < strlen(buf); i++)
    {
        ::SendMessage(g_hWnd, WM_IME_CHAR, buf[i], 0);
    }
    ::SendMessage(g_hWnd, WM_IME_CHAR, 13, 0);
    idx = sCmd.find("clean");
    if (idx == string::npos){
        Sleep(120000);
    }
    else{Sleep(5000); }
    const string& gaoci = "exit";
    buf = (char*)gaoci.c_str();
    for (i = 0; i < strlen(buf); i++)
    {
        ::SendMessage(g_hWnd, WM_IME_CHAR, buf[i], 0);
    }
    ::SendMessage(g_hWnd, WM_IME_CHAR, 13, 0);
    
    //终止进程
    if (pi.hProcess)
    {
        cout << "开始关闭编译器" << endl;
        DWORD dwEC = 0;
        BOOL b = GetExitCodeProcess(pi.hProcess, &dwEC);
        if (b)
        {
            if (!TerminateProcess(pi.hProcess, dwEC))
            { cout << "强行关闭编译器" << endl; }
        }
        CloseHandle(pi.hProcess);
        cout << "关闭编译器成功" << endl;
    }
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));
    }
    
  2. 定义getDwProcessId函数,用于监听创建子窗口的活动:

    ```c++
    //监听创建子窗口的活动
    DWORD getDwProcessId(DWORD g_dwProcessId)
    {
    int nNumberDely = 1000;
    // 等待窗口动行起,获取到窗口HWND
    while(EnumWindows(EnumWindowsProcGetWndTitle,g_dwProcessId) && nNumberDely>0 )
    {
        nNumberDely--;
    }
    return g_dwProcessId;
    }
  3. 定义EnumWindowsProcGetWndTitle回调函数,用于捕获子窗口句柄:

    ```c++
    //定义EnumWindowsProcGetWndTitle回调函数,用于捕获子窗口句柄
    BOOL CALLBACK EnumWindowsProcGetWndTitle(HWND hWnd, LPARAM lParam)
    {
    DWORD ProcID = 0;
    GetWindowThreadProcessId(hWnd, &ProcID);
    cout << "传入窗口的进程id:" << lParam << "当前窗口的进程id:" << ProcID << endl;
    cout << "当前窗口句柄:" << hWnd << endl;
    if (ProcID == lParam)//如果窗口的processid等于你的ID
    {
        HWND pWnd = GetParent(hWnd);
        cout << "第一父窗口句柄:" << pWnd << endl;
        while (GetParent(pWnd) != NULL)//得到父窗口的句柄
        {
            pWnd = GetParent(pWnd);
            cout << "父窗口句柄:" << pWnd << endl;
        }
        if (pWnd != NULL) 
        {
            g_hWnd = pWnd;
        } else 
        {
            g_hWnd = hWnd;
        }
        cout << "最终父窗口句柄:" << g_hWnd << endl;
        //ok ?pWnd 就是主窗口了。
        return FALSE;
    }
    return TRUE;
    }
  4. 参考意见和网页地址:

    1. https://blog.csdn.net/moshang005/article/details/37932455

以上是关于windows 下在进程中使用createprocess创建一个窗口进程,并获取这个窗口HWND句柄的主要内容,如果未能解决你的问题,请参考以下文章

如何在不复制的情况下在多个进程中使用大型数据集?

在不知道进程启动顺序的情况下在另一个进程上触发事件

探讨下在Delphi里面进程之间的数据共享

如何在不传递引用的情况下在 Python 中使用 SyncManager 跨进程共享列表

在Windows10下在WSL中使用visual studio code

如何在没有超时/死锁的情况下在PROMELA进程中发送和接收?