Я случайно удалил из приложения совместимость с Windows 2000 с помощью GetProcessID.
Я так использую, чтобы получить основной 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)
...
}
Есть идеи, как реализовать ту же функцию в Windows 2000?





Есть функция типа "неподдерживаемая": ZwQueryInformationProcess (): см.
http://msdn.microsoft.com/en-us/library/ms687420.aspx
Это даст вам идентификатор процесса (среди прочего) с учетом дескриптора. Не гарантируется, что это будет работать с будущими версиями Windows, поэтому я бы предложил иметь вспомогательную функцию, которая проверяет версию ОС, а затем использует GetProcAddress () для вызова GetProcessId () для XP и более поздних версий и ZwQueryInformationProcess () только для Windows 2000 .
Нет, это не ZwQueryInformationProcess () Это NtQIP и, конечно, он работает для всех версий, начиная с NT 3.5, и вам вообще не нужно тестировать ОС
похоже, нет никакой разницы между ZwQueryInformationProcess () и NtQueryInformationProcess (). В Vista они оба имеют один и тот же адрес. Оба отмечены как потенциально недоступные, поэтому для будущей совместимости необходимо тестирование ОС является.
В режиме ядра они разные.
DavidK прав. См. Комментарий в документации ZwQueryInformationProcess:
[ZwQueryInformationProcess may be altered or unavailable in future versions of Windows. Applications should use the alternate functions listed in this topic.]
Это означает, что Microsoft может удалить это в любое время в будущем, что приведет к поломке вашего приложения. Я настоятельно рекомендую вам следовать совету DavidK и использовать ZwQueryInformationProcess в ОС, которые не поддерживают GetProcessID, и использовать GetProcessID в ОС, которые его поддерживают (XP SP1 и выше).
Спасибо DavidK и Ларри - вот мое окончательное решение. Полная обработка ошибок оставлена в качестве упражнения для читателя.
Обратите внимание, что вместо того, чтобы специально проверять версию ОС, я пытаюсь динамически связываться с функциями. Статическое связывание будет означать, что приложение просто не загрузится, если процедура недоступна.
Это было успешно опробовано в Windows 2000 и 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;
}
}
Я полагаю, вы имели в виду NtQueryInformationProcess () - в чем разница между этим и ZwQueryInformationProcess ()?