眠っている間に頻繁にクラッシュする傾向のあるプログラムがあり、それを実行し続ける必要があります。そのため、プロセスリストを監視するvb6アプリケーションを作成する可能性があると思いました。何かが消えると、再起動します。誰もが簡単な方法を知っていますか?
4 に答える
EnumProcessesを使用して、実行中のシステム内のすべてのプロセスを一覧表示できます。この宣言を使用して使用できます。
Public Declare Function EnumProcesses Lib "psapi.dll" ( _
ByRef idProcess As Long, ByVal cb As Long, _
ByRef cbNeeded As Long) As Long
これを使用する前に、すべてのプロセス ID を読み取るのに十分なスペースを持つ EnumProcesses に引数として渡す Long の配列を定義する必要があります。EnumProcesses を 2 回呼び出して、その配列の大きさを調べることができます。2回目の呼び出しの後、その配列をループしてプロセスを開き、適切に使用されたハンドルを取得して、プロセスの実行可能ファイルの名前を伝え、そのデータを検索している実行可能ファイルの名前と比較することができます。それ以外の場合、たとえば探しているのが DLL である場合、そのプロセス ハンドルの EnumProcessModules は、探している dll の実行中の各プロセスを検索できます。EnumProcessModules の宣言はこれです
Public Declare Function EnumProcessModules Lib "psapi.dll" ( _
ByVal hProcess As Long, ByRef lphModule As Long, _
ByVal cb As Long, ByRef cbNeeded As Long) As Long
そして、あなたが必要とする可能性のあるコードは、このようなものになるでしょう
Option Explicit
Private Declare Function OpenProcess Lib "Kernel32.dll" ( _
ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, _
ByVal dwProcId As Long) As Long
Private Declare Function EnumProcesses Lib "psapi.dll" ( _
ByRef lpidProcess As Long, ByVal cb As Long, _
ByRef cbNeeded As Long) As Long
Private Declare Function GetModuleFileNameExA Lib "psapi.dll" ( _
ByVal hProcess As Long, ByVal hmodule As Long, _
ByVal moduleName As String, ByVal nSize As Long) As Long
Private Declare Function EnumProcessModules Lib "psapi.dll" ( _
ByVal hProcess As Long, ByRef lphModule As Long, _
ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Public Function IsModuleRunning(ByVal theModuleName As String) As Boolean
Dim aProcessess(1 To 1024) As Long ' up to 1024 processess?'
Dim bytesNeeded As Long
Dim i As Long
Dim nProcesses As Long
Dim hProcess As Long
Dim found As Boolean
EnumProcesses aProcessess(1), UBound(aProcessess), bytesNeeded
nProcesses = bytesNeeded / 4
For i = 1 To nProcesses
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, aProcessess(i))
If (hProcess) Then
Dim hmodule(1 To 1024) As Long ' no more than 1024 modules per process?'
bytesNeeded = 0
If EnumProcessModules(hProcess, hmodule(1), 1024 * 4, bytesNeeded) Then
Dim nModules As Long
Dim j As Long
Dim moduleName As String
moduleName = Space(1024) ' module name should have less than 1024 bytes'
nModules = bytesNeeded / 4
For j = 1 To nModules
Dim fileNameLen As Long
fileNameLen = GetModuleFileNameExA(hProcess, hmodule(j), moduleName, 1024)
moduleName = Left(moduleName, fileNameLen)
If Right(LCase(moduleName), Len(theModuleName)) = LCase(theModuleName) Then
found = True
Exit For
End If
Next
End If
End If
CloseHandle hProcess
If found Then Exit For
Next
IsModuleRunning = found
End Function
Private Sub Form_Load()
MsgBox IsModuleRunning("explorer.exe")
End Sub
関数コードは少し長いですが、それを呼び出すのは小さな関数です。少しテストしたい場合に使用できます:)
WMIを使用します。
VB6で行き詰まっている場合は、WebでWMI+VB6を検索してください。
それ以外の場合は、C#とWMIのインターフェイスがはるかに簡単です。
他のプログラムを実行するプログラムを使用しています。そうすれば、プロセス ハンドルをポーリングして、アプリケーションがまだ実行されているかどうかを確認できます。そうでない場合は、もう一度起動できます。API プログラミングが必要です。
スケジュールされたタスク(10分ごとに実行)を使用し、次のコンテンツでcmdファイルを開始しました:
tasklist |find "myapp.exe" >nul || c:\mypath\myapp.exe
VB6シェルからそのようなコマンドファイルを実行するか、タスクスケジューラを使用することができます:)