2008-11-07 37 views
3

我不小心通過使用GetProcessID從應用程序中刪除了Win2K兼容性。替代GetProcessID for Windows 2000

我像這樣使用它來獲取啓動應用程序的主要HWND。

ShellExecuteEx(&info); // Launch application 
HANDLE han = info.hProcess; // Get process 

cbinfo.han = han; 

//Call EnumWindows to enumerate windows.... 
//with this as the callback 

static BOOL CALLBACK enumproc(HWND hwnd, LPARAM lParam) 
{ 
    DWORD id; 
    GetWIndowThreadProcessID(hwnd, &id); 
    if (id == GetProcessID(cbinfo.han)) 
    setResult(hwnd) 
... 
} 

任何想法如何在Win2K上實現相同的功能?

回答

6

有一個 '排序不支持的,' 功能:ZwQueryInformationProcess():見

http://msdn.microsoft.com/en-us/library/ms687420.aspx

這會給你的進程ID(除其他事項外),給出的手柄。這不能保證與未來的Windows版本一起工作,所以我建議有一個幫助函數測試操作系統版本,然後使用GetProcAddress()爲XP或更高版本調用GetProcessId(),而僅爲Win2K調用ZwQueryInformationProcess() 。

-1

不,這不是ZwQueryInformationProcess() 這是NtQIP,當然它工作以來NT 3.5的所有版本,你並不需要在所有

+0

我假設你的意思NtQueryInformationProcess() - 是什麼(),它和ZwQueryInformationProcess之間的區別? – Roddy 2008-11-07 18:04:22

5

DavidK的權利來測試OS。請參閱ZwQueryInformationProcess文檔中的評論:

[ZwQueryInformationProcess可能 改變或未來不可用的Windows版本 。應用 應該使用複用功能 本主題中列出。]

這意味着微軟可以選擇在未來任何時候刪除此,破壞你的應用程序。我強烈認爲你遵循DavidK的建議,並在OS不支持GetProcessID的OS上使用ZwQueryInformationProcess,並在支持它的操作系統上使用GetProcessID(XP SP1及更高版本)。

2

感謝DavidK和Larry--這是我的最終解決方案。完整的錯誤處理作爲讀者的練習。

請注意,不是專門檢查操作系統版本,我嘗試動態鏈接到功能。靜態鏈接意味着如果程序不可用,應用程序將無法加載。

這已經成功嘗試在Win2k和Vista:

#include "Winternl.h" 

typedef DWORD (WINAPI* pfnGetProcID)(HANDLE h); 

typedef NTSTATUS (WINAPI* pfnQueryInformationProcess)(
    HANDLE ProcessHandle, 
    PROCESSINFOCLASS ProcessInformationClass, 
    PVOID ProcessInformation, 
    ULONG ProcessInformationLength, 
    PULONG ReturnLength); 

DWORD MyGetProcessId(HANDLE h) 
{ 
    static pfnQueryInformationProcess ntQIP = (pfnQueryInformationProcess) GetProcAddress(GetModuleHandle("NTDLL.DLL"),"NtQueryInformationProcess"); 
    static pfnGetProcID getPId = (pfnGetProcID) GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcessId"); 

    if ((ntQIP == NULL) && (getPId == NULL)) 
     throw Exception("Can't retrieve process ID : GetProcessID not supported"); 

    if (getPId != NULL) 
     return getPId(h); 
    else 
    { 
     PROCESS_BASIC_INFORMATION info; 
     ULONG returnSize; 
     ntQIP(h, ProcessBasicInformation, &info, sizeof(info), &returnSize); // Get basic information. 
     return info.UniqueProcessId; 
    } 
}