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

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

主要思路是:

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

图例如下:

示例如下:

  1. 程序入口点代码

   //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函数,用于监听创建子窗口的活动:**

   

  //监听创建子窗口的活动
  DWORD getDwProcessId(DWORD g_dwProcessId)
  {
  	int nNumberDely = 1000;
  	// 等待窗口动行起,获取到窗口HWND
  	while(EnumWindows(EnumWindowsProcGetWndTitle,g_dwProcessId) && nNumberDely>0 )
  	{
  		nNumberDely--;
  	}
  	return g_dwProcessId;
  }

3. **定义EnumWindowsProcGetWndTitle回调函数,用于捕获子窗口句柄:**

   //定义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