Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You don't need to go spelunking for processes just to get a handle to child processes that you spawn. The VB6 Shell() function returns a <em>Process ID</em> you can use to call <code>OpenProcess</code> with. <code>CreateProcess</code> gives you the handle directly.</p> <p>Ok, here is a super-stripped-down example of a program in VB6 to spawn and monitor programs. The example is coded to start and repeatedly restart 3 copies of the command shell (trivial sample child program). It is also written to kill any running children when it is terminated, and there are better alternatives to use in most cases. See <a href="http://drdobbs.com/184416547" rel="nofollow">A Safer Alternative to TerminateProcess()</a>.</p> <p>This demo also reports back the exit code of each process that quits. You could enter <code>exit 1234</code> or somesuch to see this in action.</p> <p>To create the demo open a new VB6 Project with a Form. Add a multiline TextBox <code>Text1</code> and a Timer <code>Timer1</code> (which is used to poll the children for completion). Paste this code into the Form:</p> <pre><code>Option Explicit Private Const SYNCHRONIZE = &amp;H100000 Private Const PROCESS_QUERY_INFORMATION = &amp;H400&amp; Private Const PROCESS_TERMINATE = &amp;H1&amp; 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") &amp; " /k ""@ECHO I am #" &amp; CStr(I) &amp; """" 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) &lt;&gt; INVALID_HANDLE And Handles(I) &lt;&gt; 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) &lt;&gt; INVALID_HANDLE Then If WaitForSingleObject(Handles(I), 0) = WAIT_OBJECT_0 Then If GetExitCodeProcess(Handles(I), ExitCode) &lt;&gt; 0 Then Text1.SelText = "Task " &amp; CStr(I) &amp; " terminated, " _ &amp; "exit code: " &amp; CStr(ExitCode) _ &amp; ", restarting task." _ &amp; vbNewLine Else Text1.SelText = "Task " &amp; CStr(I) &amp; " terminated, " _ &amp; "failed to retrieve exit code, error " _ &amp; CStr(Err.LastDllError) _ &amp; ", restarting task." _ &amp; 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 &lt;&gt; 0 Then Handles(I) = OpenProcess(SYNCHRONIZE _ Or PROCESS_QUERY_INFORMATION _ Or PROCESS_TERMINATE, 0, Pid) If Handles(I) &lt;&gt; 0 Then Text1.SelText = "Task " &amp; CStr(I) &amp; " started." _ &amp; vbNewLine Else Text1.SelText = "Task " &amp; CStr(I) _ &amp; ", failed to open child process." _ &amp; vbNewLine Handles(I) = DEAD_HANDLE End If Else Text1.SelText = "Task " &amp; CStr(I) _ &amp; ", failed to Shell child process." _ &amp; vbNewLine Handles(I) = DEAD_HANDLE End If End If Next Timer1.Enabled = True End Sub </code></pre> <p>Hopefully this helps answer the question.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload