|
|
|
2012/9/25(Tue) 10:04:46|NO.49554
具体的には、以下のようなプログラムを組みたいのですが、
打つ手がなくなったので皆様にご相談をする次第です……(;ω;)
・起動直後、自分と同じ実行ファイルが立ち上がっていたらそのプロセスを強制終了する
・立ち上がってないなら何もせず起動続行
要するに、ハングアップしているプロセスに対しタスクマネージャから「プロセスの終了」
を実行するのと同等の作業を、起動時にアプリ自身に自動的に行わせたいのです。
こうすれば、ユーザーはハング時にいちいち強制終了とかしなくても、再度実行するだけで
済むなあと。
で、色々ググってみて、EnumProcesslist等からハンドルを取得し実行ファイル名を取得して
TerminateProcessをかけるところまではできました。ところが、これだと先に実行していた
プロセスのみならず自分自身も殺してしまうため、結局ただの強制終了と同じことになって
しまうのです。
もし、プロセスリストで取得した内容が、間違いなく確実に起動された順番どおりである
のなら、プロセスを殺したらすぐループを脱出すればいいと思うのですが……
どなたか、助言をいただければ幸いに思います。
以下が、ググったのを流用したルーチン部です。(;ω;)
//========================================================================================
// プロセス殺すルーチン
// processnameに拡張子を除いたファイル名を指定する
*kill_process
; 変数の宣言
dim proc, 1000000
dim ret
; 起動中のプロセスリスト取得
EnumProcesses proc, length(proc), ret
; プロセスリストから指定のプロセスを取得
repeat ret / 4
; プロセスハンドルを取得
hProc = OpenProcess(0x400 | 0x0010 | 0x0001, 0, proc(cnt))
; プロセスハンドルが取得できたら
if hProc {
if(EnumProcessModules(hProc, list, 4, ret)) {
sdim file, 256
sdim file_name, 256
; モジュール名とモジュールのプルパス取得
GetModuleFileNameEx hProc, list, file, 256
GetModuleBaseName hProc, list, file_name, 256
; 終了させたいモジュール名だったら(小文字限定)
if(getpath(file, 16+8+1) = processname) {
; 強制終了させる
if(TerminateProcess(hProc, 0) = 0) {
dialog "終了できませんでした"
}
}
}
; プロセスハンドルを閉じる
CloseHandle hProc
}
loop
return
| |
|
2012/9/25(Tue) 10:49:02|NO.49555
追記。一応モジュール化してみました。
メモ帳を殺したいなら、kill_process "notepad"でイケます。
自分自身を殺したいなら、自分のファイル名(拡張子を除く)を指定。
試しに、上記のとおり1回殺したらすぐ脱出するようにしてみました。
タスクマネージャでPIDを観察しながら実行した限り、後から起動した自分自身を殺すことは
なさそうに見えますが……
問題ありげな感じでしたら、ぜひご指摘&ご指導を。(;ω;)
#module
//========================================================================================
// プロセス殺すルーチン
// 書式: kill_process [拡張子を除いたファイル名]
// 最初に見つけたら殺して脱出(たぶんこれでイケるはずなんだけど)
#uselib "kernel32.dll"
#cfunc OpenProcess "OpenProcess" int, int, int
#func CloseHandle "CloseHandle" int
#cfunc TerminateProcess "TerminateProcess" int, int
#uselib "psapi.dll"
#func EnumProcesses "EnumProcesses" var, int, var
#cfunc EnumProcessModules "EnumProcessModules" int, var, int, var
#func GetModuleFileNameEx "GetModuleFileNameExA" int, int, var, int
#func GetModuleBaseName "GetModuleBaseNameA" int, int, var, int
#deffunc kill_process str prname
processname = prname
; 変数の宣言
dim proc, 1000000
dim ret
; 起動中のプロセスリスト取得
EnumProcesses proc, length(proc), ret
; プロセスリストから指定のプロセスを取得
repeat ret / 4
; プロセスハンドルを取得
hProc = OpenProcess(0x400 | 0x0010 | 0x0001, 0, proc(cnt))
; プロセスハンドルが取得できたら
if hProc {
if(EnumProcessModules(hProc, list, 4, ret)) {
sdim file, 256
sdim file_name, 256
; モジュール名とモジュールのプルパス取得
GetModuleFileNameEx hProc, list, file, 256
GetModuleBaseName hProc, list, file_name, 256
; 終了させたいモジュール名だったら(小文字限定)
if(getpath(file, 16+8+1) = processname) {
; 強制終了させる
if(TerminateProcess(hProc, 0) = 0) {
; 失敗の場合は1を返す
return 1
}
; プロセスハンドルを閉じ、ループ脱出
CloseHandle hProc
break
}
}
; プロセスハンドルを閉じる
CloseHandle hProc
}
loop
return 0
#global
| |
|
2012/9/25(Tue) 17:42:44|NO.49556
起動時に、自分以外の同名プロセスを終了させるようにしてみました。
//========================================================================================
// プロセス殺すルーチン
// 書式: kill_process [拡張子を除いたファイル名]
// 最初に見つけたら殺して脱出(たぶんこれでイケるはずなんだけど)
#module
#uselib "kernel32.dll"
#cfunc OpenProcess "OpenProcess" int, int, int
#cfunc TerminateProcess "TerminateProcess" int, int
#func CloseHandle "CloseHandle" int
#func GetModuleFileName "GetModuleFileNameA" int, int, int
#uselib "psapi.dll"
#func EnumProcesses "EnumProcesses" var, int, var
#func GetModuleFileNameEx "GetModuleFileNameExA" int, int, var, int
#deffunc kill_process str prname
processname = prname
dim proc, 1000000
dim PID_targ, 10
dim ret
i = 0
EnumProcesses proc, length(proc), ret
repeat ret / 4
hProc = OpenProcess(0x400 | 0x0010 | 0x0001, 0, proc(cnt))
if hProc {
sdim file, 256
GetModuleFileNameEx hProc, list, file, 256
if(getpath(file, 16+8+1) = processname) {
PID_targ(i) = cnt
i++
}
CloseHandle hProc
}
loop
if i=1 : return 0
repeat i-1
if hProc {
hProc = OpenProcess(0x400 | 0x0010 | 0x0001, 0, proc(PID_targ(cnt)))
if hProc {
res = TerminateProcess(hProc, 0)
CloseHandle hProc
}
}
loop
return 0
#deffunc RunOnlyOne
sdim filepath, 256
GetModuleFileName 0, varptr(filepath), 256
kill_process getpath(filepath, 9)
return
#global
RunOnlyOne
| |
|
2012/9/25(Tue) 19:34:37|NO.49559
おおおおおおおおお!(*゚ω゚*)
・GetModuleFileNameで自分自身のプロセスの実行ファイルパスを取得
・同名プロセスの数をカウントし、1コだけなら処理おわり
・複数あるなら、最後のを残して後は全部殺しとく
という改造ですね、なるほど!
ていうか、やっぱプロセスリストの一番最後のが必然的に自分のプロセスだと解釈して
いいってことですね。なるほど、勉強になりました、感謝です!(´ω`)
|
|