自分が起動した後に起動したプロセスのProcessID(PID)を取得
可憐 2013/6/19(Wed) 20:17:42|NO.55084
自分が起動した後に起動したプロセスのProcessID(PID)を取得したいです。
自分が起動する前に既に起動しているプロセスののProcessIDは取得しないで。
こんな事はできますか?
ソース、アドバイス等頂けると光栄です。
KA 2013/6/19(Wed) 20:24:27|NO.55085
1:起動後のプロセスを列挙し保存する。
2;定期的に比較する。
3:再起動されたプロセスは御自由に。
可憐 2013/6/19(Wed) 20:56:38|NO.55087
お便りありがとうございます。
2番3番は分かるのですが
1番の方法がよくわかりません。
全てのプロセスを列挙してしまいます。
起動後ののみができません…
ht. 2013/6/19(Wed) 21:10:22|NO.55088
ですから定期的に全てのプロセスを列挙しておき、その都度以前のプロセスリストとの差分を比較すれば最初にあったプロセスを除外したものが絞れるということです。
名無し 2013/6/19(Wed) 21:21:13|NO.55089
可憐さん
もう少し良く考えてみてください。必ずできるはずです。
ht. 2013/6/19(Wed) 22:25:15|NO.55093
書いてみましたがきっと重たいと思うのであんまり多用するべきではありません。
HSPでなければOpenProcessをフックするのが一番でしょうが。
#uselib "kernel32"
#func OpenProcess "OpenProcess" int, int, int
#func CloseHandle "CloseHandle" int
#uselib "psapi"
#func EnumProcesses "EnumProcesses" int, int, int, int
#func EnumProcessModules "EnumProcessModules" int, int, int, int
#func GetModuleFileNameEx "GetModuleFileNameExA" int, int, int, int
#define PROCESS_ALL_ACCESS $001F0FFF
dim pids, 1024
dim opids, 1024
sdim file_name, 256
title "2秒毎に新規プロセスを検出"
mes "execute any process now."
repeat
gosub *enum_process
wait 200
loop
*enum_process
EnumProcesses varptr(pids), length(pids) * 4, 0
if __cashed {
repeat length(pids)
i = cnt
matched = 0
repeat length(opids)
if pids.i == opids.cnt {
matched = 1
break
}
loop
if matched : continue
OpenProcess PROCESS_ALL_ACCESS, 0, pids.i
hpro = stat
hmod = 0
EnumProcessModules hpro, varptr(hmod), 4, 0
GetModuleFileNameEx hpro, hmod, varptr(file_name), 256
CloseHandle hpro
mes file_name
loop
} else {
__cashed = 1
}
memcpy opids, pids, length(pids) * 4
return
可憐 2013/6/19(Wed) 22:32:48|NO.55094
皆さんありがとうございます。
htさんのソース、C:なんちゃらーと表示されますが、
ときどき?ななんちゃらーと表示されてしまいますがこれは
ただのバグですか?
htさんのソースを頑張って勉強してPID取得まで頑張って見ますかね!
長いソース、まとこにありがたいです。
ht. 2013/6/19(Wed) 22:42:57|NO.55095
OpenProcessをフックすればと書きましたがCreateProcessのミスでした。どうでもいいですが。
>可憐さん
「?」だけならGetModuleFileNameExが失敗したときに確認済みですがそれ以外は見たことがありません。
特定のプロセスに対して再現性があるなら仕様ということになりそうです。
このスクリプト自身、他のサイトを参考に即興で書いたものなので不完全な可能性もありますが。
可憐 2013/6/19(Wed) 22:47:09|NO.55096
関数の失敗で起こる現象なんですね!
分かりました!
頑張ってみます!!
inovia 2013/6/19(Wed) 23:23:16|NO.55097
GetModuleFileNameExの前に、
memset file_name, 0, 256
を入れ、NULL埋めをしておいた方が良いかと思います。
ゴミが混入して、
?:\hsp332\hsp3.exe
となってる時があります。
あと、GetModuleFileNameExだと、32bitプロセス(HSP)は
64bitプロセスのプロセス名を取得できないようなので(?になる)、
64bitプロセスのプロセス名も必要な場合は、
GetProcessImageFileNameを使うと良いかもしれません。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx
ただ、
\Device\Harddisk2\hsp332\hsp3.exe
のようなパスが返ってくる難点はありますが。
変換する方法もなくはないようです。
http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vclng.cgi?print+201010/10100011.txt
ht. 2013/6/19(Wed) 23:56:52|NO.55098
>inoviaさん
いずれも初耳で勉強になりました。
貴重な情報提供ありがとうございます。
可憐 2013/6/20(Thu) 01:18:32|NO.55100
やっぱPID取得できなかったです…
MillkeyStars 2013/6/20(Thu) 05:52:05|NO.55102
サンプルのみ。
ただし、中途半端にしか作ってないので、改良してください。
#uselib "psapi.dll"
#func global EnumProcesses "EnumProcesses" var,int,var
#module _PID_GETSTRING_
#deffunc GetPIDList var _EnumStringBuffer
dim _PID,1024
_WritePIDByte = 0
EnumProcesses _PID,length(_PID) * 4,_WritePIDByte
_PID_MAX = _WritePIDByte / 4
_EnumStringBuffer = ""
repeat _PID_MAX
_EnumStringBuffer += strf("EP%06d",_PID(cnt))
loop
return
#global
sdim EnumString_Def,(1024 * 8) + 1
sdim EnumString_Aft,(1024 * 8) + 1
GetPIDList EnumString_Def //←起動直後のプロセスリストを取得(自身も含む)
*main
GetPIDList EnumString_Aft
if EnumString_Aft = EnumString_Def : wait 200 : goto *main
//相違があるので、違うプロセスを検索
mes "プロセスリストの内容の違い"
def_size = strlen(EnumString_Def)
aft_size = strlen(EnumString_Aft)
if ( def_size == aft_size ) : mes "プロセス個数は同じだけど、プロセスIDが違う。"
if ( def_size > aft_size ) : mes "終了したプロセスがある。"
if ( def_size < aft_size ) : mes "新しく起動したプロセスがある。"
//デフォルトのプロセスリストの更新
GetPIDList EnumString_Def
wait 200
goto *main
mes "終了したプロセスがある。" 付近の行のスクリプトを改良すれば、判別はできる。
同じ個数だった場合は、比較元と比較先のプロセスリストを比較し、違うプロセスだけ抜き出せばいい。
その後の正確なプロセスID及びプロセスの実行ファイル名などは、ht.さんの OpenProcess で取得すればいい。
ただし、終了したプロセスの実行ファイル名だけは、後取得できないので、事前に保存しておく必要がある。
可憐 2013/6/20(Thu) 05:58:16|NO.55103
できました!
回答者さんありがとうございました!