- ベストアンサー
GetModuleFileNameでエラーが出てしまう。
#include<windows.h> #include<string.h> // 関数のプロトタイプ宣言 VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime); BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam); // エントリポイント int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; EnumWindows((WNDENUMPROC)EnumWindowsProc,NULL); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam) { char Caption[201]; char FileName[1024]=""; char FindList[1][80]={"Microsoft Internet Explorer"}; GetWindowText(hwnd, Caption, 200); for(int i=0;i<=0;i++) if(NULL!=strstr(Caption,FindList[i])) { HINSTANCE hInst; hInst = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE); if(GetModuleFileName(hInst, FileName, 1023)!=0) { // ファイル名取得成功したときの動作 MessageBox(NULL,Caption,FileName,MB_OK|MB_SETFOREGROUND); }else{ MessageBox(NULL,Caption,"Error",MB_OK|MB_SETFOREGROUND); } } return true; } 実行するとIEが起動されてたらそのウインドウのキャプションとプログラム名を表示される予定なのですが、 GetModuleFileNameでエラーが返されます。 何が原因なのでしょう?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
DLLを注入して、モジュール名を取得する方法です。 1.GetWindowProcessTheradIdで対象プロセスのThreadIDを取得 2.ThreadIDを指定し、SetWindowsHookExでWH_GETMESSAGEでメッセージフックをかける 3.対象のウィンドウに、WM_USER等の独自定義メッセージを送る。 4.フックプロシージャの中で、GetModuleHandleやGetWndowLongでインスタンスハンドルを取得し、GetModuleFileNameを使用してモジュール名を取得。 5.取得したプロセス名を自アプリに渡す。 共有メモリでもWM_COPYDATAでも何でもかまわない。 てな感じで出来ます。 この方法のメリットとしては、相手プロセスの、メモリ空間で動作するので何でも出来ることです。 デメリットは、危険なところです(^^;; 作成したDLLにバグがあると、相手プロセスを落とすことになります。 また、相手アプリが異常終了したりすると、DLLが開放されない事態も発生します。 ちなみにGetWindowModuleFileName、古いSDKだと定義されていないかもしれませんね。 以前は隠し関数?だったのかな? 最新のWindowsSDKを取得して使用することをお勧めします。 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/getwindowmodulefilename.asp
その他の回答 (2)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>何が原因なのでしょう? プロセスが違うからです。 Win32では、モジュールハンドルはプロセスごとに独立しているため、 GetModuleFileNameでは別のプロセス内容を取得できないからです。 取得するには、フックを使ってDLLをそのプロセスのアドレス空間に読み込ませ、そこで実行することになります。 グローバルフックは不可です。 ウィンドウハンドルが分かっているので、スレッドIDを指定してメッセージフックがいいでしょう。
とりあえず GetLastError() してみるとか…。 自分のプロセス空間に無いものは GetModuleFileName() で取得できなさそうですが。 ウィンドウハンドルからプログラム名を取得するには GetWindowModuleFileName というAPIがあります。
補足
>GetLastError() ハンドルが無効ですと出ました。 >GetWindowModuleFileName コンパイラにそんな関数はないと言われました。 どうやって使うのでしょうか?
お礼
回答ありがとうございます。 具体的にどのようなプログラムを書けばよいのでしょうか? おしえてください。 旅行へ行くため返事が遅れるかもしれません。