2011-06-17 5 views
5

別のVB6アプリケーションのインスタンスを実行し、実行中のプロセスを監視するために、VB6で少しのアプリケーションを書く必要がありますが、VB6でプロセス情報を取得する方法はわかりません。私はtasklistユーティリティで必要なものを見ることができますが、プロセスの作成(可能であればプロセスやアプリケーション名の指定)や、オペレーティングシステムからプロセスに関する情報を取得する方法はわかりません。VB6のプロセスモニタ/ディスパッチャ

このアプリケーションは、Windows XPマシンで実行します。

誰かがこの種のことについてゲットしたチュートリアルや役に立つWebページを知っていますか?

答えて

6

これを行うために使用できるWindows API関数は数多くあります。まず、実行中のすべてのプロセスに関する情報を収集するために使用できるEnumProcessesVB6 example and declaration here)を見てみましょう。 OpenProcess を使用して、特定のプロセス(another VB6 example)についてのWindowsの問い合わせを開始することもできます。

fairly nice example on MSDNもあります。

そしてもちろん、CreateProcessは産卵のプロセスのために(AllApi link)またはShellExecuteAllApi)がある - 後者ははるかに簡単な呼び出しです前者は、あなたのプロセスの作成をより細かく制御できます。

There was another question posted about this a while back with some example code.

別の可能なアプローチは、WMIsome useful snippets to adapt)を使用することであろう。

最後に、ここでそれを行う方法をお見せいくつかのチュートリアルがある(私は:)のに最初にそれを自分でしようとお勧めします:

ここにいくつかの関連する質問がありますが、投稿前にこのサイトを検索したときにおそらくすでに見たことがあります:

3

あなたは**他のアプリケーションでも** VB6であると言うので、ActiveX EXEに他のアプリケーションを作るために容易になるだろう。次に、他のアプリケーションのオブジェクトへの参照を、最初のアプリケーションから直接得ることができます。 COMはあなたのためにそれをすべて解決します。

+0

この技術は確かにそのアプリケーションを持っていると私は一つの可能​​性として自分自身をそれをお勧めしたいのオプションを持って家の中で行われている場合にのみ適用されます申し訳ありません新しい作品のセラチンの種類のために。しかし、子どものプログラムがあなたによって書かれていない場合でもそれはあまり役に立ちませんし、それでもかなりの書き換えが必要になります。また、多くのシナリオでは欠点となりうるプロセス外COM登録が必要です。 – Bob77

2

です。VB6 Shell()関数はプロセスIDを返します。OpenProcessを呼び出すために使用できます。 CreateProcessはハンドルを直接提供します。

ここでは、プログラムを起動して監視するためのVB6のプログラムのスーパーストリップダウンの例を示します。この例では、コマンドシェルの3つのコピーを開始して繰り返し再起動するようにコード化されています(簡単なサンプルの子プログラム)。また、実行中の子プロセスが終了したときに、実行中の子プロセスを強制終了するように記述されています。ほとんどの場合、より良い代替方法があります。 A Safer Alternative to TerminateProcess()を参照してください。

このデモでは、終了する各プロセスの終了コードも表示します。これを実際に見るには、exit 1234と入力してください。

デモを作成するには、フォームを使用して新しいVB6プロジェクトを開きます。複数行TextBox Text1とタイマーTimer1(子を完了するためにポーリングするために使用されます)を追加します。このコードをフォームに貼り付けてください。

Option Explicit 

Private Const SYNCHRONIZE = &H100000 
Private Const PROCESS_QUERY_INFORMATION = &H400& 
Private Const PROCESS_TERMINATE = &H1& 
Private Const WAIT_OBJECT_0 = 0 
Private Const INVALID_HANDLE = -1 
Private Const DEAD_HANDLE = -2 

Private Declare Function CloseHandle Lib "kernel32" (_ 
    ByVal hObject As Long) As Long 

Private Declare Function GetExitCodeProcess Lib "kernel32" (_ 
    ByVal hProcess As Long, _ 
    ByRef lpExitCode As Long) As Long 

Private Declare Function OpenProcess Lib "kernel32" (_ 
    ByVal dwDesiredAccess As Long, _ 
    ByVal bInheritHandle As Long, _ 
    ByVal dwProcessId As Long) As Long 

Private Declare Function TerminateProcess Lib "kernel32" (_ 
    ByVal hProcess As Long, _ 
    ByVal uExitCode As Long) As Long 

Private Declare Function WaitForSingleObject Lib "kernel32" (_ 
    ByVal hHandle As Long, _ 
    ByVal dwMilliseconds As Long) As Long 

Private Tasks() As String 
Private Handles() As Long 

Private Sub Form_Load() 
    Dim I As Integer 

    'We'll run 3 copies of the command shell as an example. 
    ReDim Tasks(2) 
    ReDim Handles(2) 
    For I = 0 To 2 
     Tasks(I) = Environ$("COMSPEC") & " /k ""@ECHO I am #" & CStr(I) & """" 
     Handles(I) = INVALID_HANDLE 
    Next 
    Timer1.Interval = 100 
    Timer1.Enabled = True 
End Sub 

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) 
    Dim I As Integer 

    Timer1.Enabled = False 
    DoEvents 
    For I = 0 To UBound(Tasks) 
     If Handles(I) <> INVALID_HANDLE And Handles(I) <> DEAD_HANDLE Then 
      TerminateProcess Handles(I), 666 
      CloseHandle Handles(I) 
      Handles(I) = DEAD_HANDLE 
     End If 
    Next 
End Sub 

Private Sub Timer1_Timer() 
    Dim I As Integer 
    Dim ExitCode As Long 
    Dim Pid As Long 

    Timer1.Enabled = False 
    For I = 0 To UBound(Tasks) 
     If Handles(I) <> INVALID_HANDLE Then 
      If WaitForSingleObject(Handles(I), 0) = WAIT_OBJECT_0 Then 
       If GetExitCodeProcess(Handles(I), ExitCode) <> 0 Then 
        Text1.SelText = "Task " & CStr(I) & " terminated, " _ 
            & "exit code: " & CStr(ExitCode) _ 
            & ", restarting task." _ 
            & vbNewLine 
       Else 
        Text1.SelText = "Task " & CStr(I) & " terminated, " _ 
            & "failed to retrieve exit code, error " _ 
            & CStr(Err.LastDllError) _ 
            & ", restarting task." _ 
            & vbNewLine 
       End If 
       CloseHandle Handles(I) 
       Handles(I) = INVALID_HANDLE 
      End If 
     End If 
     If Handles(I) = INVALID_HANDLE Then 
      Pid = Shell(Tasks(I), vbNormalFocus) 
      If Pid <> 0 Then 
       Handles(I) = OpenProcess(SYNCHRONIZE _ 
             Or PROCESS_QUERY_INFORMATION _ 
             Or PROCESS_TERMINATE, 0, Pid) 
       If Handles(I) <> 0 Then 
        Text1.SelText = "Task " & CStr(I) & " started." _ 
            & vbNewLine 
       Else 
        Text1.SelText = "Task " & CStr(I) _ 
            & ", failed to open child process." _ 
            & vbNewLine 
        Handles(I) = DEAD_HANDLE 
       End If 
      Else 
       Text1.SelText = "Task " & CStr(I) _ 
           & ", failed to Shell child process." _ 
           & vbNewLine 
       Handles(I) = DEAD_HANDLE 
      End If 
     End If 
    Next 
    Timer1.Enabled = True 
End Sub 

これは質問に答えるのに役立ちます。

+0

CreateProcessは子プロセスを作成しますが、自立したプロセスは作成しません。私は、モニター/ディスパッチャーが混乱して崩壊した場合、プロセスが継続して実行されることを期待していました。 –

+0

Windowsのプロセスファミリーリンケージは、通常、かなり弱いです。子プロセスは、親プロセスが終了しても実行を継続します。 – Bob77

+0

Er、上記のコメントは、CreateProcess()またはVBのShell()の一般的な使用について話していました。追加したコードサンプルは、終了時に明示的に子を強制終了します。 – Bob77

0

もっと単純なものがソケットを使用します。

あなたのアプリケーションサーバーを起動し、クライアント上であなたのサーバーとの通信を実装します。これであなたは相互コミュニケーションを提供します。

私は言う。私はいけないので、することはあなたがしようとするものであること

あなたのクライアントは、私はあなたが追加、変更