Как мне получить дескриптор конкретного открытого окна?

Во-первых, у меня очень ограниченные знания C ++.

Пару лет назад мне удалось сколотить код, который считывает область памяти какого-то программного обеспечения для эмуляции фруктовых автоматов. Он работал на основе заголовка окна фруктового автомата с буквами «DX».

Я использовал следующий код:

    if (strstr(lpszTitle, "DX") && !strstr(lpszTitle, "=")) {
        cout << "\nFound fruity with name: " << lpszTitle << "\n";
        currentWindowName = lpszTitle;

        // Found "DX" in the title of the window
        // so it must be an MFME window
        GetWindowThreadProcessId(hWnd, &pid);
        HANDLE phandle = OpenProcess(PROCESS_VM_READ, 0, pid);

        if (!phandle)
        {
            cout << "\nCould not get handle!\n";
            soundHopperAlarm(5); // "Error, could not get window process handle"
            cin.get();
        }
        else
        { // rest of code here...

Тогда кто-то сказал мне, что лучший способ получить дескриптор окна - это код:

wchar_t process[] = L"MFME.exe";
DWORD pid= GetPID(process);
HANDLE phandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ, false, pid);

Я не менял свой код, потому что (в то время) он соответствовал моей цели. Я просто изменил все "фруктовые машины", которые я эмулировал, чтобы в их заголовке был текст "DX", и все заработало ...

Однако в настоящее время я пытаюсь добавить в систему более 1000 фруктовых автоматов, и было бы НАМНОГО проще, если бы существовал более надежный метод получения дескриптора окна без необходимости изменять каждый заголовок окна.

Я действительно не могу понять новый код, и простое копирование / вставка в мой существующий код вызывает ошибки, связанные с неопределенностью GetPID, поэтому я подумал, может ли кто-нибудь помочь мне с надежным решением для получения дескриптора окна, открытого с помощью " MFME.exe?

Любая помощь / руководство очень ценится.


person John T    schedule 22.09.2019    source источник
comment
См. Перечисление процессов и Перечисление всех процессов в MSDN. Но лично, вместо того, чтобы перечислять процессы, я бы перечислял окна и просто следил за тем, чтобы у фруктовых окон было уникальное и согласованное имя класса, а не заголовок, тогда вы можете использовать FindWindow/Ex() или GetClassName(), чтобы найти их.   -  person Remy Lebeau    schedule 22.09.2019
comment
@RemyLebeau благодарим вас за помощь и ссылки. Я прочту их сегодня и посмотрю, смогу ли я осмыслить это. Спасибо :-)   -  person John T    schedule 23.09.2019


Ответы (1)


Чтобы получить дескриптор процесса (дескриптор процесса с желаемыми разрешениями, а не дескриптор окна HWND), вам может потребоваться запустить вашу программу от имени администратора. Если вы запускаете его из отладчика VS, вам также нужно будет запустить процесс VS как администратор.

Вот код, использующий CreateToolHelp32Snapshot для перечисления процессов, чтобы получить правильный.

#include <Windows.h>
#include <tlhelp32.h>

DWORD GetProcId(const char* procName)
{
    DWORD procId = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 procEntry;
        procEntry.dwSize = sizeof(procEntry);

        if (Process32First(hSnap, &procEntry))
        {
            do
            {
                if (!_stricmp(procEntry.szExeFile, procName))
                {
                    procId = procEntry.th32ProcessID;
                    break;
                }
            } while (Process32Next(hSnap, &procEntry));

        }
    }
    CloseHandle(hSnap);
    return procId;
}

int main()
{
    DWORD procId = GetProcId("MFME.exe");

    HANDLE hProc = 0;
    hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ, false, procId);

    std::cout << std::hex << "0x" << hProc << std::endl;

    std::getchar();
    return 0;
}

Это должно удовлетворить ваши потребности

person GuidedHacking    schedule 15.02.2020