Альтернатива GetProcessID для Windows 2000

Я случайно удалил из приложения совместимость с 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?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
3 791
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Есть функция типа "неподдерживаемая": ZwQueryInformationProcess (): см.

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

Это даст вам идентификатор процесса (среди прочего) с учетом дескриптора. Не гарантируется, что это будет работать с будущими версиями Windows, поэтому я бы предложил иметь вспомогательную функцию, которая проверяет версию ОС, а затем использует GetProcAddress () для вызова GetProcessId () для XP и более поздних версий и ZwQueryInformationProcess () только для Windows 2000 .

Нет, это не ZwQueryInformationProcess () Это NtQIP и, конечно, он работает для всех версий, начиная с NT 3.5, и вам вообще не нужно тестировать ОС

Я полагаю, вы имели в виду NtQueryInformationProcess () - в чем разница между этим и ZwQueryInformationProcess ()?

Roddy 07.11.2008 21:04

похоже, нет никакой разницы между ZwQueryInformationProcess () и NtQueryInformationProcess (). В Vista они оба имеют один и тот же адрес. Оба отмечены как потенциально недоступные, поэтому для будущей совместимости необходимо тестирование ОС является.

Roddy 11.11.2008 13:25

В режиме ядра они разные.

ChristianWimmer 23.07.2010 02:08

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;
    }
}

Другие вопросы по теме