【问题标题】:Alternative to GetProcessID for Windows 2000Windows 2000 的 GetProcessID 的替代方法
【发布时间】:2008-11-07 13:17:08
【问题描述】:

我使用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 上实现相同的功能?

【问题讨论】:

    标签: c++ windows winapi


    【解决方案1】:

    有一个“不支持的”函数:ZwQueryInformationProcess():见

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

    给定句柄,这将为您提供进程 ID(以及其他内容)。这不能保证适用于未来的 Windows 版本,所以我建议有一个帮助函数来测试操作系统版本,然后使用 GetProcAddress() 来调用 XP 及更高版本的 GetProcessId() 和 ZwQueryInformationProcess() 仅用于 Win2K .

    【讨论】:

      【解决方案2】:

      DavidK 是对的。请参阅 ZwQueryInformationProcess 文档中的注释:

      [ZwQueryInformationProcess 可能是 将来更改或不可用 Windows 版本。应用 应该使用替代功能 在本主题中列出。]

      这意味着微软可以选择在未来的任何时候删除它,从而破坏你的应用程序。我强烈认为您遵循 DavidK 的建议并在不支持 GetProcessID 的操作系统上使用 ZwQueryInformationProcess 并在支持它的操作系统上使用 GetProcessID(XP SP1 及更高版本)。

      【讨论】:

        【解决方案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;
            }
        }
        

        【讨论】:

          【解决方案4】:

          不,不是 ZwQueryInformationProcess() 它是 NtQIP,当然它适用于 NT 3.5 以来的所有版本,您根本不需要测试操作系统

          【讨论】:

          • 我假设你的意思是 NtQueryInformationProcess() - 那和 ZwQueryInformationProcess() 有什么区别?
          • ZwQueryInformationProcess() 和 NtQueryInformationProcess() 之间似乎没有区别。在 Vista 上,它们都具有相同的地址。两者都被标记为可能不可用,因此测试操作系统对于未来的兼容性是必要的
          • 在内核模式下它们是不同的。
          猜你喜欢
          • 1970-01-01
          • 2023-03-04
          • 2015-01-08
          • 2021-09-11
          • 1970-01-01
          • 2012-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多