#c #windows #winapi #setwindowshookex
#c #Windows #winapi #setwindowshookex
Вопрос:
Я создаю программу на основе руководства и хочу иметь возможность подключать свой код к определенным приложениям, чтобы руководство взаимодействовало с приложением.
Мой код подключения работает для большинства приложений, кроме Google Chrome. Я сократил свой код до следующего, чтобы вы могли видеть, что все идет неправильно.
Main.cpp
#include <Windows.h>
#include <iostream>
#include <psapi.h>
#include <Tlhelp32.h>
unsigned long GetProcId( const std::stringamp; name )
{
unsigned long res = 0 ;
HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 processInfo ;
processInfo.dwSize=sizeof(PROCESSENTRY32W);
if( !Process32First( hSnapShot, amp;processInfo ) )
{
CloseHandle( hSnapShot );
return res ;
}
do
{
if( NULL != ( strstr ( strlwr ( processInfo.szExeFile ), name.c_str() ) ) )
{
res = processInfo.th32ProcessID ;
break ;
}
} while(Process32Next( hSnapShot,amp;processInfo ));
CloseHandle( hSnapShot ) ;
return res ;
}
typedef LRESULT (CALLBACK *DllHookProc)(int nCode, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
unsigned int processid = GetProcId( "chrome.exe" ) ;
if (processid == 0)
{
return 0 ;
}
HINSTANCE dllInstance = LoadLibrary("mydll.dll") ;
if (dllInstance == NULL)
{
return 0 ;
}
DllHookProc hookProc = (DllHookProc)::GetProcAddress(dllInstance, "HookProc");
if ( hookProc == NULL)
{
FreeLibrary(dllInstance);
return 0 ;
}
HHOOK hook = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)hookProc,
dllInstance, processid );
if (hook == NULL)
{
FreeLibrary(dllInstance);
return 0 ;
}
return 0 ;
}
Тестовая Dll (mydll.dll )
LRESULT CALLBACK HookProc (int nCode, WPARAM wParam, LPARAM lParam )
{
//Pass to the next chain in the process list
return CallNextHookEx( 0, nCode, wParam, lParam);
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}
Файл определения
LIBRARY "MYDLL"
EXPORTS
HookProc @1
Все работает нормально (включая получение ProcessId и загрузку библиотеки и getprocaddress) вплоть до SetWindowsHookEx, который возвращает NULL с кодом ошибки 87 (недопустимый параметр).
Оба chrome.exe
и мой код являются 32-разрядными.
Работает ли это у кого-нибудь еще или кто-нибудь знает, что это не работает?
Спасибо
Ответ №1:
Вы понимаете, что chrome использует многопроцессорную модель, верно? Многие экземпляры Chrome взаимодействуют, и у некоторых из них может не быть очереди событий.
Скорее всего, ваш GetProcId
код не будет работать в Chrome, потому что он находит только один соответствующий процесс.
Ответ №2:
Одна из возможных проблем может заключаться в том, что вы создаете 64-битный код, но chrome.exe
он 32-битный (или наоборот). [Смотрите комментарий и обновление, это не тот случай.]
Одна подозрительная вещь в вашем коде заключается в том, что вы не вызываете Process32First
, и это, похоже, требуется. Смотрите, например: Создание моментального снимка и просмотр процессов.
Последнее предложение: вы передаете идентификатор процесса в SetWindowsHookEx
, но при этом ожидается идентификатор потока.
Комментарии:
1. Спасибо за ответ, но они оба 32-разрядные
2. Исправлена ошибка с Process32First. Я исправил код, но, к сожалению, проблема все та же. Еще раз спасибо
3. Это решило проблему, большое спасибо! Однако в Chrome потенциально запущено много потоков, поэтому есть ли способ, которым я могу найти идентификатор основного потока GUI, чтобы я знал, что моя dll не будет выгружена, пока они не выйдут из chrome? Еще раз спасибо, вы оказали большую помощь
4. Извините, не знаю об этом — на самом деле я не программирую в Windows 🙂 Задайте отдельный вопрос.
5. «Однако в Chrome потенциально запущено множество потоков, поэтому есть ли способ, которым я могу найти идентификатор основного потока графического интерфейса» — лучшее, что можно сделать, это найти HWND в Chrome, который вас интересует, и использовать GetWindowThreadProcessId, чтобы получить идентификатор этого потока. Также рекомендую использовать Spy , чтобы проверить, как структурированы окна и каким процессам / потокам они принадлежат, но имейте в виду, что Chrome может изменить способ их работы на каком-то этапе в будущем. На данный момент похоже, что все HWND в chrome принадлежат одному потоку, за исключением некоторых окон плагинов.