何時も参考にさせていただいています。
もんちきTwin Truboと申します。
皆様にご教授いただきたく、書き込みさせていただきます。
現在、OpenProcessを使用して、実行中のプロセスの一覧を取得しようとしています。
作成に当たっては、以下のスレッドを参考にさせていただいています。
https://www.petitmonte.com/bbs/answers?question_id=1652
しかし、期待するように動作しません。
例えば、上記のサンプルでは、メモ帳の起動を検知できません。
原因を調べるため、途中のプロセス一覧を取得する部分で、以下の2行を追加し、値の変化を確認してみました。そうしたところ、インデックスiは正常に増加しますが、hProcessが変化しません。
for i := 0 to NumProcess -1 do begin
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
false, ProcessIDs[i]);
ShowMessage(IntToStr(i));//追加
ShowMessage(IntToStr(hProcess));//追加
EnumProcessModules(hProcess,@hModule,SizeOf(hModule),Num4);
Num4 := GetModuleBaseName(hProcess,hModule,lpBaseName,100);
SetString(s,lpBaseName,Num4);
SL.Add(s);
CloseHandle(hProcess);
end;
OSや言語のバージョンの違いによるものでしょうか?
OSは64bit Windows7 professional
Delphiは7です。
よろしくおねがいします。
そもそもEnumProcessesが返す値はどうなっていますか?EnumProcessesはプロセスを列挙しきれなくても検知できないので
Win32API EnumProcesses(プロセス列挙)の使い方 | 豆知識
http://soundengine.jp/wordpress/tips/tutorial/336/
こんなことが必要ですけどどうでしょう?
Windows7からは他のプロセスの状態を取得しようとしても全てのプロセスが取得出来ない場合があります。
取得方法はMr.XRAY様のページが参考になるかと
http://mrxray.on.coocan.jp/Delphi/plSamples/330_AppProcessList.htm
管理者権限でないと取得出来ないプロセスの場合、管理者権限への昇格が必要なのですが
Windows7からはプログラム中に管理者権限に昇格しようとするとOSが確認メッセージを出して
一時的に処理を止めるかもしれません。
通りすがり様、take様、ご回答ありがとうございます。
>通りすがり様
>そもそもEnumProcessesが返す値はどうなっていますか?
参考にした過去ログのプログラムでは、ループに入る前にEnumProcessesを以下のように実行しています。
ループが実行されていると言うことは、ここでtrue(0以外?)が返っているのだと思います。
if not EnumProcesses(@ProcessIDs,SizeOf(ProcessIDs),Num4) then begin
ShowMessage('EnumProcesses Failed!');
Exit;
end;
またこの前に以下の2行を追加し引数を確認したところ、それぞれ804と29374392でした。
(最初の@ProcessIDsについては、ポインタのキャストの仕方が良く分かりませんでした。)
showmessage(IntToStr(SizeOf(ProcessIDs)));
showmessage(IntToStr(Num4));
これについて変化を見たところ、SizeOf(ProcessIDs)は再起動してもexeから起動しても804で変化せず、
Num4は随時変化しました。また、その後ろの
NumProcess := Num4 div SizeOf(DWORD);
は、その時々の起動中のプロセス数を返します。
ProcessIDsが変化しないことが要因なのでしょうか??
>take様
>取得方法はMr.XRAY様のページが参考になるかと
Mr.XRAY様のプロジェクトを参考にさせていただきました。
Mr.XRAY様のプロジェクトに包含されているexeファイルは、どれも正常に動作しました。
また、take様のご指摘通り、管理者権限で実行した場合とそうでない場合で、列挙されるプロセスは変化しました。
ただ、Mr.XRAY様のプロジェクトを自分の環境で開きコンパイルすると、プロセス名は全て C 一文字
(恐らくドライブレター?)になってしまいました。
氏のプロジェクトはWindows 7 U64(SP1) + Delphi XE Proということでしたが、私のDelphiは7なので、
コンパイラの問題によるということでしょうか?
Mr.XRAY様のサンプルが Delphi2009以降の文字コードで処理されているようなので
Delphi7 だと string の定義を WideStringにする必要があるかもしれません。
取得する処理のところでブレークポイントを付けてどこで情報が欠落してしまうのかがわかれば改善出来るかと思います。
>Mr.XRAY様のサンプルが Delphi2009以降の文字コードで処理されているようなので
>Delphi7 だと string の定義を WideStringにする必要があるかもしれません。
ですね.
これはサンプルにもよります.使用する関数名の変更が必要な場合もあります.
Delphi 2007 以前のコードを Delphi 2009 以降に移植する場合も同じです.
参考
[DLL 内の関数の使用方法 - DLL と目的の関数が必ず存在する場合]
http://mrxray.on.coocan.jp/Delphi/Others/Usage_Win32API.htm#03
take様
>Delphi7 だと string の定義を WideStringにする必要があるかもしれません。
そうなんですね。
とりあえず、ExePathをWideStringに変更しました。
>取得する処理のところでブレークポイントを付けてどこで情報が欠落してしまうのかがわかれば改善出来るかと思います。
Mr.XRAY様のサンプル06_Toolhelp32Snapshot_FullPathをベースにしています。
Button1Clickの中で値を見てみました。
ListHandle 起動時の値は同じ(起動時の権限によって値は異なる)
以降時々変化
ProcEntry.dwSize 権限等に関わらず常に一定(296)
ループ 1 2 3 4 5 ...
ProcessID :0 4 300 460 512 ...
hProcHandle:0 472 472 472 472 ...
同梱のexeが正常に動くので、私が何か間違えているとは思うのですが…
Mr.XRAY様、ご回答ありがとうございます。
書き込みが前後して、申し訳ありません。
>これはサンプルにもよります.使用する関数名の変更が必要な場合もあります.
関数名の変更が必要な場合もあるのですね。
この場合、psapi.dllに仕様が分からないといけないということですね…
勉強しなきゃならないことがいっぱいです。
>この場合、psapi.dllに仕様が分からないといけないということですね…
そうなんですか ? よく意味が理解できませんが,
私が貼ったリンクの記事,お読み頂けました ?
[06_Toolhelp32Snapshot を使用したプロセスの列挙でフルパスを取得]
http://mrxray.on.coocan.jp/Delphi/plSamples/330_AppProcessList.htm#06
↑ が Delphi 7 で動作すればいいんでしょうか ?
(このようにリンクを貼れば,他の方もすぐ参照できます.
このぐらいの手間をかけても損はないと思いますし,私もすぐ調べられます)
参考
[DLL 内の関数の使用方法 - DLL と目的の関数が必ず存在する場合]
http://mrxray.on.coocan.jp/Delphi/Others/Usage_Win32API.htm#03
の記事に
>実際には,Delphi 2007 以前では,末尾が A の関数を使用します.
と書いてあります.
ですので,
QueryFullProcessImageNameW
↓ 変更
QueryFullProcessImageNameA
にします.
当方の 64 ビット Windows 7 (SP1) + Delphi 7 ではこれで動作しました.
Mr.XRAY様
ご回答、ありがとうございます。
>そうなんですか ? よく意味が理解できませんが,
>私が貼ったリンクの記事,お読み頂けました ?
私の知識ではすぐには十分理解できなかったので、まだ読んでいる最中です。ただdllの引数の型がDelphiの型と一致しない場合があることは分かりましたので、dllから呼び出す関数の仕様を良く理解する必要があるのですね…という趣旨で書きました。
>(このようにリンクを貼れば,他の方もすぐ参照できます.
>このぐらいの手間をかけても損はないと思いますし,私もすぐ調べられます)
済みません。決して手間を惜しんだ訳ではなく、個人様のHPに直接リンクを張って良いものか分からなかったので、あのような書き方にしました。気をつけます。
ご指摘の通りQueryFullProcessImageNameAに変更したら、期待通りに動作しました。
どうもお手数をおかけしました。申し訳ありません。
皆様、ありがとうございました。
ツイート | ![]() |