dポイントプレゼントキャンペーン実施中!

ウィンドウのハンドルからファイル名を取得する方法について質問です。

GetWindowThreadProcessIdで、スレッドのIDを取得、
OpenProcessで、ハンドルを開く、
EnumProcessModulesで、モジュールのハンドルを取得、
GetModuleFileNameExで、パス名を取得、
でファイル名を取得しようとしているのですが一部のウィンドウのハンドルは失敗します。
Windows XPでは取得できるのですが、Windows 7では失敗します。
EnumProcessModulesで取得が失敗しているようです。
私の予想ではOpenProcessでのアクセス権の指定に問題があるのではと
思って調べてみたのですが分かりませんでした。

GetWindowModuleFileNameでも試してみたのですが、
取得に失敗します。

ちなみに、OpenProcessのアクセスフラグは
「PROCESS_QUERY_INFORMATION | PROCESS_VM_READ」です。

どうすればいいのでしょうか?
他の方法があれば、それでも構いません。
とにかく、他のウィンドウ(プロセス)のファイル名を取得出来れば、
どんな方法でも構いません。
よろしくお願いします。

A 回答 (2件)

Windows7 64bit、Visual Studio 2008 Standard、ビルド:x64


で試してみましたが、EnumProcessModules でのエラーはありませんでした。
普通に実行すると OpenProcess でのエラーが 22件となりましたが、「管理者として実行」で実行すると OpenProcess でのエラーは 2件になりました。
「管理者として実行」でも EnumProcessModules でのエラーはありませんでした。


BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam );
void OutputError( HWND hwnd, LPTSTR pMessage );

int _tmain(int argc, _TCHAR* argv[])
{
EnumWindows( EnumWindowsProc, 0 );
return 0;
}

BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
{
TCHAR fileName[ MAX_PATH ];
DWORD processID = NULL;
GetWindowThreadProcessId( hwnd, &processID );
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID );
if( hProcess ) {
HMODULE hModule = NULL;
DWORD dummy = 0;
if( EnumProcessModules( hProcess, &hModule, sizeof(HMODULE), &dummy ) ) {
memset( fileName, 0, MAX_PATH );
DWORD returnValue = GetModuleFileNameEx( hProcess, hModule, fileName, MAX_PATH );
if( returnValue ) {
_tprintf( _T("%08x:%s\n"), hwnd, fileName );
} else {
OutputError( hwnd, _T("GetModuleFileNameEx") );
}
} else {
OutputError( hwnd, _T("EnumProcessModules") );
}
CloseHandle( hProcess);
} else {
OutputError( hwnd, _T("OpenProcess") );
}
return TRUE;
}

void OutputError( HWND hwnd, LPTSTR pMessage )
{
TCHAR Caption[ 200 ];
DWORD errorCode = GetLastError();
_tprintf( _T("%08x:%s Error:%08x"), hwnd, pMessage, errorCode );
if( GetWindowText( hwnd, Caption, 200 ) ) {
_tprintf( _T(":%s\n"), Caption );
} else {
_tprintf( _T("\n") );
}
}

この回答への補足

調べてみると、Win32コンソールアプリケーションでは取得に成功するのですが、
Win32プロジェクトでは取得に失敗することが分かりました。

原因をもう少し調べてみようと思います。

補足日時:2011/05/22 12:57
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

載せていただいたもので試してみたのですが、
エラーは出ませんでした。
何度も見直したのでミスはないとは思うのですが、
載せていただいたもので出来ているのでどこかが間違っているはずなので、
再度ミスが無いか確認してみようと思います。

お礼日時:2011/05/22 11:17

もしかして、



Windows XP : 32bit
Windows7 : 64bit
実行するプログラム : Win32

だったりしませんか?
もし、64bit 環境なら、プラットフォームを x64 にしてビルドしないと x64 のプロセスのところでエラーになると思います。

この回答への補足

回答ありがとうございます。
環境を書き忘れてました。
すみません。

開発環境は、Windows7、64bit、Visual C++ 2010 Expressです。
プラットフォームはx64でビルドしています。
ちなみに、プラットフォームをx32でビルドしても失敗しました。
XPは32bitです。

補足日時:2011/05/21 19:45
    • good
    • 0
この回答へのお礼

空いている入力欄がここだけだったのでこちらで書かせていただきます。

新しくプロジェクトを作成して試したら取得できました。
作っているプロジェクト(ファイル)と、テスト用に前に作っていた
プロジェクトで試していて、
それでは失敗していたので、恐らくプロジェクトファイルが破損していたか、
設定が勝手に変わっていたのではないかと私の予想ですが、そう思います。
何が原因だったかは正確には分かりませんが、解決できて良かったです。

>調べてみると、Win32コンソールアプリケーションでは取得に成功するのですが、
>Win32プロジェクトでは取得に失敗することが分かりました。
と書いたのですが、関係ありませんでした。

ありがとうございました。

お礼日時:2011/05/22 14:53

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!