Process ID, Process handle, Window handle
I am confused about what you know and what you still need to know. Some of your statements seem to be contradicting, so I will tell you some possibilities:
1)
HAVE: Process ID, NEED: Process handle
Solution: OpenProcess()
2)
HAVE: Process handle, NEED: Process ID
Solution: GetProcessId()
3)
HAVE: Window handle, NEED: Process ID
Solution: GetWindowThreadProcessId()
4)
HAVE: Window handle, NEED: Process handle
Solution: Use 3) and then 1)
5)
HAVE: Process ID, NEED: Window handle
Solution: EnumWindows(), then in the callback function do 3) and check if it matches your process ID.
6)
HAVE: Process handle, NEED: Window handle
Solution: 2) and then 5)
http://www.programlife.net/get-main-window-handler-in-dll.html
有的时候难免需要在DLL中获取主进程的窗口句柄,比如在DLL注入的时候等等。那么如何在DLL中获取主进程的窗口句柄呢?可以通过EnumWindows来实现。先通过GetCurrentProcessId获取进程的PID,然后在EnumWindows中调用GetWindowThreadProcessId获得与窗口句柄关联的进程PID,然后对比PID,看是否相等,并判断是不是主窗口即可。
以上方法参考自网络,不一定很完善,但是通常情况下已经够用了。附上测试代码:
// Author: 代码疯子 // Blog: http://www.programlife.net/ #include <windows.h> BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { DWORD dwCurProcessId = *((DWORD*)lParam); DWORD dwProcessId = 0; GetWindowThreadProcessId(hwnd, &dwProcessId); if(dwProcessId == dwCurProcessId && GetParent(hwnd) == NULL) { *((HWND *)lParam) = hwnd; return FALSE; } return TRUE; } HWND GetMainWindow() { DWORD dwCurrentProcessId = GetCurrentProcessId(); if(!EnumWindows(EnumWindowsProc, (LPARAM)&dwCurrentProcessId)) { return (HWND)dwCurrentProcessId; } return NULL; } BOOLEAN WINAPI DllMain( IN HINSTANCE hDllHandle, IN DWORD nReason, IN LPVOID Reserved) { BOOLEAN bSuccess = TRUE; switch ( nReason ) { case DLL_PROCESS_ATTACH: MessageBox(GetMainWindow(), TEXT("OMG~ You are Attacked!"), TEXT("Warning"), MB_ICONWARNING); break; case DLL_PROCESS_DETACH: break; } return bSuccess; }
ProcessID, Process Handle, Window Handle 之间的互相转换
http://www.delphitop.com/html/jincheng/219.html
// Get ProcessID By ProgramName (Include Path or Not Include) function GetPIDByProgramName(const APName: string): THandle; // Get Window Handle By ProgramName (Include Path or Not Include) function GetHWndByProgramName(const APName: string): THandle; // Get Window Handle By ProcessID function GetHWndByPID(const hPID: THandle): THandle; // Get ProcessID By Window Handle function GetPIDByHWnd(const hWnd: THandle): THandle; // Get Process Handle By Window Handle function GetProcessHndByHWnd(const hWnd: THandle): THandle; // Get Process Handle By Process ID function GetProcessHndByPID(const hAPID: THandle): THandle;
// Get Window Handle By ProgramName (Include Path or Not Include) function GetHWndByProgramName(const APName: string): THandle; begin Result:=GetHWndByPID(GetPIDByProgramName(APName)); end; // Get Process Handle By Window Handle function GetProcessHndByHWnd(const hWnd: THandle): THandle; var PID: DWORD; AhProcess: THandle; begin if hWnd<>0 then begin GetWindowThreadProcessID(hWnd, @PID); AhProcess := OpenProcess(PROCESS_ALL_ACCESS, false, PID); Result:=AhProcess; CloseHandle(AhProcess); end else Result:=0; end; // Get Process Handle By Process ID function GetProcessHndByPID(const hAPID: THandle): THandle; var AhProcess: THandle; begin if hAPID<>0 then begin AhProcess := OpenProcess(PROCESS_ALL_ACCESS, false, hAPID); Result:=AhProcess; CloseHandle(AhProcess); end else Result:=0; end; // Get Window Handle By ProcessID function GetPIDByHWnd(const hWnd: THandle): THandle; var PID: DWORD; begin if hWnd<>0 then begin GetWindowThreadProcessID(hWnd, @PID); Result:=PID; end else Result:=0; end; // Get Window Handle By ProcessID function GetHWndByPID(const hPID: THandle): THandle; type PEnumInfo = ^TEnumInfo; TEnumInfo = record ProcessID: DWORD; HWND: THandle; end; function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall; var PID: DWORD; begin GetWindowThreadProcessID(Wnd, @PID); Result := (PID <> EI.ProcessID) or (not IsWindowVisible(WND)) or (not IsWindowEnabled(WND)); if not Result then EI.HWND := WND; //break on return FALSE 所以要反向檢查 end; function FindMainWindow(PID: DWORD): DWORD; var EI: TEnumInfo; begin EI.ProcessID := PID; EI.HWND := 0; EnumWindows(@EnumWindowsProc, Integer(@EI)); Result := EI.HWND; end; begin if hPID<>0 then Result:=FindMainWindow(hPID) else Result:=0; end; // Get ProcessID By ProgramName (Include Path or Not Include) function GetPIDByProgramName(const APName: string): THandle; var isFound: boolean; AHandle, AhProcess: THandle; ProcessEntry32: TProcessEntry32; APath: array[0..MAX_PATH] of char; begin try Result := 0; AHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); ProcessEntry32.dwSize := Sizeof(ProcessEntry32); isFound := Process32First(AHandle, ProcessEntry32); while isFound do begin AhProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, ProcessEntry32.th32ProcessID); GetModuleFileNameEx(AhProcess, 0, @APath[0], sizeof(APath)); if (UpperCase(StrPas(APath)) = UpperCase(APName)) or (UpperCase(StrPas(ProcessEntry32.szExeFile)) = UpperCase(APName)) then begin Result := ProcessEntry32.th32ProcessID; break; end; isFound := Process32Next(AHandle, ProcessEntry32); CloseHandle(AhProcess); end; finally CloseHandle(AHandle); end; end;