HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0201
こいる特定のウィンドウの実行ファイルのフルパスを取得したい9解決


こいる

リンク

2020/2/1(Sat) 18:32:01|NO.89386

現在開いている特定のウィンドウの実行ファイルのフルパスを取得したいです。

//メモ帳の実行ファイルのフルパスを取得したいサンプル #uselib "user32.dll" #cfunc global FindWindow "FindWindowA" sptr,sptr #func global GetWindowModuleFileName "GetWindowModuleFileNameA" sptr,sptr,sptr sdim buf,256 dim wh wh = FindWindow("Notepad",0) GetWindowModuleFileName wh,varptr(buf),256 mes wh dialog buf end
FindWindowでメモ帳のクラス名「Notepad」を探して、ウィンドウハンドルを取得。
GetWindowModuleFileNameでウィンドウハンドルから実行ファイルのフルパスを取得できるはずなのですが、
なぜかうまくいきません。

GetModuleFileNameExというのも使ってみたのですが、
モジュールが含まれているプロセスのハンドルだとか、
モジュールのハンドルだとか、よくわかりませんでした。

ウィンドウハンドルかクラス名から取得できると良いです。
よろしくお願いします。



この記事に返信する


あらや

リンク

2020/2/1(Sat) 19:57:22|NO.89389

GetWindowModuleFileNameの使い方が分からなかったので。

割り切ってGetModuleFileNameExでやってみました。
パスを取得するだけならモジュールのハンドルは不要ですし
プロセスハンドル取得は以前のスレッドと似たような流れです。
http://hsp.tv/play/pforum.php?mode=all&num=89047


//メモ帳の実行ファイルのフルパスを取得したいサンプル #uselib "user32.dll" #cfunc global FindWindow "FindWindowA" sptr,sptr #func global GetWindowThreadProcessId "GetWindowThreadProcessId" int, var #uselib "kernel32.dll" #cfunc global OpenProcess "OpenProcess" int, int, int #func global CloseHandle "CloseHandle" int #uselib "psapi.dll" #func global GetModuleFileNameEx "GetModuleFileNameExA" int, int, var, int #define global PROCESS_ALL_ACCESS 0x001F0FFF sdim buf,256 wh = FindWindow("Notepad",0) GetWindowThreadProcessId wh, ProcessId; // ウィンドウハンドルからプロセスID取得 PhWnd = OpenProcess( PROCESS_ALL_ACCESS, 0, ProcessId); // プロセスIDからプロセスハンドル取得 GetModuleFileNameEx PhWnd, 0, buf, 256; // 実行ファイルのフルパス取得 CloseHandle PhWnd; // プロセスハンドルが不要になったら閉じる mes wh dialog buf



あらや

リンク

2020/2/1(Sat) 21:04:24|NO.89390

追記です。

GetWindowModuleFileNameに関して調べてみた所、
「自分のプロセスに関する場合にしか使えない」という内容の情報がありました。
(他アプリのパス取得には使えない)

試しに自身のウィンドウハンドルを指定してみると

GetWindowModuleFileName hWnd,varptr(buf),256
サラッとHSPの実行ファイルのパスが取得出来ました。


ほかにもNT系のWindowsでは
「GetWindowModuleFileName も GetModuleFileName もダメだ」
という情報もありましたので、
GetModuleFileNameExを利用するのが無難かと思います。



こいる

リンク

2020/2/1(Sat) 21:23:22|NO.89391

返信ありがとうございます。

>「自分のプロセスに関する場合にしか使えない」という内容の情報がありました。
そうだったのですか……。通りでできないわけで。
GetModuleFileNameも同じみたいですね。

提示してくださったスクリプトを実行してみたのですが、
メモ帳が起動していても、起動していなくても
なぜか「A」の一文字だけしか取得できませんでした。

OSはWindows8.1です。



こいる

リンク

2020/2/1(Sat) 21:27:42|NO.89392

追記

18行目を

GetWindowThreadProcessId hWnd, ProcessId
に変更してHSPのウィンドウに対して使ってみましたが、正常に動作しました。



あらや

リンク

2020/2/1(Sat) 23:10:10|NO.89394

>メモ帳が起動していても、起動していなくても
>なぜか「A」の一文字だけしか取得できませんでした。
すみません、こちらでは再現できませんでした。
(Windows10です)

念のためにAPIの引数部分をsptrに変更してみたり、
HSP3.51での実行、3.6β2で実行、
hsp3utfで実行、hsp3_64で実行なども確認してみましたが
失敗したときにはパスに何も入らず
成功時はちゃんとメモ帳のパスが取得出来ました。

失敗はAPIの引数のvarの箇所をsptrに書き換え、
使用時にvarptrを使っていなかったので失敗して当然なのですが……
その他の場合は全て成功しました。

取得したパスの文字列をUnicodeに変換なども試しましたが、
その場合は「C」(Windowsのインストール先がCドライブなので)とだけ表示されました。

Windowsのバージョンに寄る物なのか、その他何らかの環境によるのか
確認が出来ないため、申し訳ないのですが私には回答が出来ません<(_ _)>



ooo

リンク

2020/2/2(Sun) 03:03:56|NO.89397

確かwin32bitアプリから64bitアプリに対してGetModuleFileNameExなどは使えなかったと
思ったのですがwin10だと動きますね。
win8.1ではQueryFullProcessImageNameが使えます。

http://hsp.tv/play/pforum.php?mode=pastwch&num=65277



こいる

リンク

2020/2/2(Sun) 15:11:40|NO.89401

>確かwin32bitアプリから64bitアプリに対してGetModuleFileNameExなどは使えなかったと
>思ったのですがwin10だと動きますね。

試しに32bitのアプリに対して使ってみると、見事取得ができました。


>win8.1ではQueryFullProcessImageNameが使えます。

おっしゃる通り、リンク先のモジュールを使うとできました!

一応、できたものを置いておきます。

// モジュール ;http://hsp.tv/play/pforum.php?mode=pastwch&num=65277#65323 #module #uselib "user32.dll" #cfunc GetWindowThreadProcessID "GetWindowThreadProcessId" sptr, sptr #uselib "kernel32.dll" #cfunc OpenProcess "OpenProcess" sptr, sptr, sptr #func CloseHandle "CloseHandle" sptr #func QueryFullProcessImageName "QueryFullProcessImageNameA" sptr,sptr,sptr,sptr #deffunc GetProcessName int _hwnd_, var pName dim ret sdim pName, 256 sdim FilePath, 1024 thID = GetWindowThreadProcessId(_hwnd_, varptr(PId)); // ウィンドウハンドルからプロセスID取得 hProcess = OpenProcess(0x001F0FFF, 1, PId); // プロセスIDからプロセスハンドル取得 if hProcess != 0 { size=1024 QueryFullProcessImageName hProcess, 0, varptr(FilePath), varptr(size); // フルパス取得 len = stat; // 戻り値 if len = 0 : ret = -1; } else { ret = -2 } CloseHandle hProcess; // プロセスハンドルを閉じる pName = FilePath if ret:pname=""+ret return ret #global // メモ帳の実行ファイルのフルパスを取得するサンプル #uselib "user32.dll" #cfunc global FindWindow "FindWindowA" sptr,sptr exec "C:\\Windows\\Sysnative\\notepad.exe" // 64bitメモ帳を起動 sdim pName, 256 wh = FindWindow("Notepad",0) // ウィンドウハンドル取得 GetProcessName wh , pName // フルパス取得 redraw 0 color : boxf color 255,255,255 pos 0,0 : mes pName redraw 1 gsel 0,2 stop // おまけ:マウスカーソル直下のウィンドウの実行ファイルのフルパスを取得するサンプル ;http://hsp.tv/play/pforum.php?mode=pastwch&num=65277#65307 #uselib "user32.dll" #cfunc WindowFromPoint "WindowFromPoint" int,int #cfunc GetAncestor "GetAncestor" int,int #define GA_ROOT 2 sdim pName, 256 repeat GetProcessName GetAncestor(WindowFromPoint(ginfo_mx,ginfo_my),GA_ROOT) , pName redraw 0 color : boxf color 255,255,255 pos 0,0 : mes pName redraw 1 await 100 loop stop

ところでQueryFullProcessImageNameは環境依存などあるのでしょうか?



ooo

リンク

2020/2/3(Mon) 05:52:46|NO.89408

>ところでQueryFullProcessImageNameは環境依存などあるのでしょうか?
Windows Vista以降なら問題なく使えます。
XP以前では使えません。



こいる

リンク

2020/2/3(Mon) 13:18:37|NO.89410

>Windows Vista以降なら問題なく使えます。
>XP以前では使えません。

それならば、特に問題はなさそうです。


お二人ともありがとうございました!



ONION software Copyright 1997-2018(c) All rights reserved.