2008-11-07 69 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; 
    } 
}