我使用GetProcessID意外删除了应用程序的Win2K兼容性。
我像这样使用它来获取已启动应用程序的主要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上实现相同的功能?
答案 0 :(得分:6)
有一种'不支持的'功能:ZwQueryInformationProcess():见
http://msdn.microsoft.com/en-us/library/ms687420.aspx
给定句柄,这将为您提供进程ID(以及其他内容)。这不能保证适用于未来的Windows版本,因此我建议使用一个帮助函数来测试操作系统版本,然后使用GetProcAddress()为XP及更高版本调用GetProcessId(),并仅为Win2K调用ZwQueryInformationProcess()
答案 1 :(得分:5)
DavidK是对的。请参阅ZwQueryInformationProcess文档中的注释:
[ZwQueryInformationProcess可能是 将来改变或不可用 Windows版本。应用 应该使用备用功能 本主题中列出的内容。]
这意味着Microsoft可以选择在将来的任何时候删除它,从而破坏您的应用程序。我强烈认为你遵循DavidK的建议并在操作系统上使用不支持GetProcessID的ZwQueryInformationProcess,并在支持它的操作系统上使用GetProcessID(XP SP1及更高版本)。
答案 2 :(得分:3)
感谢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;
}
}
答案 3 :(得分:-1)
不,这不是ZwQueryInformationProcess() 它是NtQIP,当然它适用于自NT 3.5以来的所有版本,你根本不需要测试操作系统