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

このQ&Aのポイント
  • ウィンドウのハンドルからファイル名を取得する方法について質問です。
  • Windows XPでは取得できるのですが、Windows 7では失敗します。
  • 他のウィンドウ(プロセス)のファイル名を取得する方法について教えてください。
回答を見る
  • ベストアンサー

ウィンドウのハンドルからファイル名を取得について

ウィンドウのハンドルからファイル名を取得する方法について質問です。 GetWindowThreadProcessIdで、スレッドのIDを取得、 OpenProcessで、ハンドルを開く、 EnumProcessModulesで、モジュールのハンドルを取得、 GetModuleFileNameExで、パス名を取得、 でファイル名を取得しようとしているのですが一部のウィンドウのハンドルは失敗します。 Windows XPでは取得できるのですが、Windows 7では失敗します。 EnumProcessModulesで取得が失敗しているようです。 私の予想ではOpenProcessでのアクセス権の指定に問題があるのではと 思って調べてみたのですが分かりませんでした。 GetWindowModuleFileNameでも試してみたのですが、 取得に失敗します。 ちなみに、OpenProcessのアクセスフラグは 「PROCESS_QUERY_INFORMATION | PROCESS_VM_READ」です。 どうすればいいのでしょうか? 他の方法があれば、それでも構いません。 とにかく、他のウィンドウ(プロセス)のファイル名を取得出来れば、 どんな方法でも構いません。 よろしくお願いします。

noname#154655
noname#154655

質問者が選んだベストアンサー

  • ベストアンサー
回答No.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") ); } }

noname#154655
質問者

お礼

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

noname#154655
質問者

補足

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

その他の回答 (1)

回答No.1

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

noname#154655
質問者

お礼

空いている入力欄がここだけだったのでこちらで書かせていただきます。 新しくプロジェクトを作成して試したら取得できました。 作っているプロジェクト(ファイル)と、テスト用に前に作っていた プロジェクトで試していて、 それでは失敗していたので、恐らくプロジェクトファイルが破損していたか、 設定が勝手に変わっていたのではないかと私の予想ですが、そう思います。 何が原因だったかは正確には分かりませんが、解決できて良かったです。 >調べてみると、Win32コンソールアプリケーションでは取得に成功するのですが、 >Win32プロジェクトでは取得に失敗することが分かりました。 と書いたのですが、関係ありませんでした。 ありがとうございました。

noname#154655
質問者

補足

回答ありがとうございます。 環境を書き忘れてました。 すみません。 開発環境は、Windows7、64bit、Visual C++ 2010 Expressです。 プラットフォームはx64でビルドしています。 ちなみに、プラットフォームをx32でビルドしても失敗しました。 XPは32bitです。

関連するQ&A

  • ウインドウハンドルとインスタンスからファイル名を求めたい。

    ウインドウハンドルとインスタンスからEXEのファイル名を求める方法が知りたいです。 ウインドウハンドルとインスタンス両方から求めるのではなく、それぞれ別の目的で使うので、 ウインドウハンドルからファイル名を求める方法と、 インスタンスからファイル名を求める方法を教えてください。

  • プロセスのハンドルと識別子

    エディットやボタンなどへのアクセスは、ウインドウハンドルを使ってそれらのオブジェクトにアクセスしているんだと考えられますが、 プロセスやスレッドにはハンドルと識別子の両方があるので、その違いが分かりません。 あるスレッドが動いていて、それを止める場合、そのスレッドのハンドルを使うのか識別子を使うのかが想像できるようになりたいのです。 プロセスを終わらせる関数を見つけ、その関数の引数の型を調べるのではなく、ハンドルと識別子の違いを理解して、それを想像する方法を教えてください。

  • プロセスIDからウィンドウハンドルを取得する方法

    以下の方法を調べていますが、プロセスIDからウィンドウハンドルを取得する方法がわかりませんでした。 (1)自分がCreateProcessで生成したプロセスのウィンドウハンドル (2)自分とは関係ないプロセスで、プロセスIDだけ判明しているプロセスのウィンドウハンドル ご存知の方、ご教授願います。 <環境> WindowsXP VC++6.0

  • 自作関数内でウインドウハンドルを得る方法

    ウインドウハンドルを渡さない自作関数で、自分の元のウインドウ (オーナーウインドウというものだと思います)を得る方法を教えてください。 まず簡単に取得できるのは、自分の実行ファイルのパスやスレッドIDです。 ここからハンドルを得るにはどういう関数を使えばいいですか?

  • ウィンドウハンドルの取得方法

    ダイアログの表示されないEXEを起動させて、FindWindowを使用してそのEXEのウィンドウハンドルを取得したいのですが上手くいきません・・。 FindWindowの第一引数は「ウィンドウのクラス名」を指定するようなのですが、「ウィンドウのクラス名」の意味が良くわかりません。第二引数は「ウィンドウ名」を指定するようなのですが、今回のようなアンダーグラウンドで動くEXEには「ウィンドウ名」は無いと思ってよいのでしょうか? ちなみにダイアログのあるEXEならウィンドウハンドルを取得できます。 お分かりの方がいらっしゃれば、ご教授願います。

  • 表示されているファイルの完全パスの取得

    Windows上で、最前面に表示されているOfficeファイルの 完全パスを取得したいのですが、方法がわかりません。 GetForegroundWindowにてハンドルを取得し、 GetWindowThreadProcessId → EnumProcessModules → GetModuleFileNameExで、取得できるのは当然のことながら、 起動したOfficeアプリの完全パス(C:\Program Files~\POWERPNT.EXE等)に なってしまいます。 取得したいのは、アプリの完全パスではなく、 ファイル自体の完全パス(C:\Documents and Setting~新規ファイル.ppt等)なんですが、 どうにかして、最前面に表示されているウィンドウ(Officeアプリ)から 表示しているファイル自体の完全パスを取得する方法はないでしょうか? よろしくお願いします。 開発環境:Visual Studio2008 / C++プロジェクト

  • ThreadのHandleの取得方法を教えて下さい。

    VCでTerminateThreadを使用して、Threadを終了させたいと思っています。 そのときに、実行中のThreadのHandleを取得したいのですが、良い方法があれば教えてください。

  • エクセル2003VBAにて、ファイルを開くダイアログのハンドルを取得し

    エクセル2003VBAにて、ファイルを開くダイアログのハンドルを取得したいのですができません。 ファイルを開くダイアログの入力欄に、 ファイルパスを入れようと思っているのですが、 ファイルを開くダイアログのウインドウハンドルが取得できません。 下記コードのhDlgの値が0となってしまいます。 '最前面(ファイルを開くダイアログ)のウィンドウハンドル取得 hDlg = FindWindowA("#32770", "Open") 'ファイル名入力欄のハンドルを取得 hInput = FindWindowExA(hDlg, 0, "Edit", vbNullString) ファイルを開くダイアログのウィンドウハンドルをどうやってとるのか、 教えていただけないでしょうか。 お手数をおかけしますが、どうぞよろしくお願いいたします。

  • 既存プロセスからプロセスのプライマリースレッドIDの取得方法

    いつもお世話になってます。 プロセスに関することで分からないことがあるため、どなたか御教授して下さい。 只今、VC++で開発を行っているのですが、CreateProcess関数を使用して開始したプロセスの情報が、引数で指定したPROCESS_INFORMATIONにプライマリースレッドのハンドルやIDが設定されるのは知っているのですが、現在動作中のプロセスからそのプロセスのプライマリースレッドのIDを取得することは可能でしょうか? 具体的には、動作中のプロセスIDを指定するとそのプロセスのプライマリースレッドに対してPostThreadMessageで任意のメッセージが送れるという仕様です。 対象のプロセスがウィンドウを持っていれば、EnumWindows関数を使用してウィンドウに対してPostMessageができるというのは分かったのですが、今回対象のプロセスがウィンドウを持たない為、上記のようにスレッドに対してメッセージを送るようになっています。 CreateProcess呼び出し時にはスレッドIDが取得できることから、プロセスID、または、プロセスハンドルからスレッドIDが取得できるのではないかなと考えられるんですが。。。。

  • C++ 子ウィンドウのハンドルを取得したいのですが

    C++で別ウィンドウのアプリケーションを動かすというものを作っているのですが、そのウィンドウの子ウィンドウのハンドルを取得するのに困ったことがあるのでアドバイスをいただけると大変ありがたいです。 基本的にSPY++というソフトを使ってウィンドウ名その他を探し、FindWindowExまたはGetDlgItem関数を使って取得という方法をとっているのですが、クラス名、ウィンドウ名が全く同じもので、コントロールIDも0という状態のものがあり、片方を取得したい場合どうしたらよいのかという状態です。 知人にSPY++でみて上から何番目にあるやつと指定して得ることができる方法があるかもしれないと聞いたのですが、よくわかりません。 例としてその画像ものせますので、良い知恵がありましたらお貸しください。

専門家に質問してみよう