[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference abbott::visual_basic

Title:Microsoft Visual Basic
Moderator:TAMARA::DFEDOR::fedor
Created:Thu May 02 1991
Last Modified:Thu Jun 05 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2565
Total number of notes:10453

2531.0. "Process termination" by SHOGUN::JAMBU_S (Skating away on the thin ice of a new day) Wed Apr 02 1997 18:23

    Is there a way to determine the pid of a process that has terminated.
    	we are writinga visual basic application where we have to 
    determine when a particular process has terminated.  How do 
    we do this? Or is it a question meant for the VB notes file
    
    Thanks
    
    Suresh
T.RTitleUserPersonal
Name
DateLines
2531.1Depends what you really require.....?CHEFS::TREVENNOR_AA child of initThu Apr 03 1997 08:5221
    Suresh,
    		Do you mean that you want to know the PID, or do you just
    want to know when a program you have launched has exited? If the former
    I don't know. If the latter use the "Shell" function within VB and then
    use the API call GetModuleUsage which is part of WinApi - something
    like this:
    
    static A,B,C as long
    
    A=Shell("C:\windows\mplayer c:\windows\tada.wav")
    While (getmoduleusage(A)) 
    debug.print "NOt done yet."
    doevents
    loop
    
    Or something like that.
    
    Rgds
    Alan T.
    
    
2531.2SHOGUN::JAMBU_SSkating away on the thin ice of a new dayThu Apr 03 1997 10:402
    Actually all I need to know is when the process has exited.
    So my guess is this approach will work
2531.3OK, try this then.CHEFS::TREVENNOR_AA child of initThu Apr 03 1997 12:5131
    
    There are some caveats to using this approach if you are running
    complex programs which spawn other tasks or threads or which use
    subsidiary run-time modules which may stick around after the launched
    program exits (some games fall into that category). In that case you
    will have to use other calls (e.g. GetNumtasks). But for the simple
    case something like the following (drawn from actual code) will work:
    
    ' Paste this into a new module.
    ' Note the _ are line continuation chars
    ' for VB Version 4. Make one screen line for V3.
     Declare Function GetModuleUsage _
       Lib "kernel32" Alias "getmoduleusage" _
         (ByVal hModule As Integer) As Integer
    
    
    
    ' Paste Stuff below into a new form.
    Static ModuleId as integer
    
    ModuleId = Shell("c:\windows\notepad.exe", 1)
    
    while (GetModuleUsage(ModuleId) <> 0)
      DoEvents
      debug.print "Waiting for notepad to exit"
    wend
    
    debug.print "Yo! The launched notepad is done."
    
    end
       
2531.4SHOGUN::JAMBU_SSkating away on the thin ice of a new dayThu Apr 03 1997 17:136
   >> while (GetModuleUsage(ModuleId) <> 0)
     
    THis always stays as 0, wonder if getmoduleusage works only with 
    programs called with loadmodule or freemodule
    
    
2531.5SHOGUN::JAMBU_SSkating away on the thin ice of a new dayThu Apr 03 1997 17:377
    I take it back... 
    getmoduleusage works fine for simple proegrams, but what I need
    is for an setup.exe, which launches multiple windows.  So looks like
    the caevats are kicking in.
    
    
    Suresh
2531.6Perhaps a combinatory approach then.....CHEFS::TREVENNOR_AA child of initFri Apr 04 1997 06:5629
    Yep it looks like it's caveat time. There is no easy answer to this. I
    have (with mostly success) used a conditional combination of the
    following steps:
    
    1) Prep steps. Write a simple program which figures out whether your
    the application you want to watch has any permanant effect on the
    overall task count in your machine. Some programs (as I said I've been
    dealing with games for our project) fire off companion tasks or threads
    which linger after the program itself exits. So, you need to figure out
    if the TaskCount (as returned from:
    
    Declare Function GetNumTasks Lib "Kernel" () As Integer
    
    is affected by the app you are monitoring.
    
    2) Armed with the info from (1) and the basic knowledge that the App
    you launched (as opposed to it's friends) has gone away you should be 
    able to combine the taskcount and the moduleID usage going to zero to
    make a program that can detect the termination of your application.
    
    In our application (which controls a bunch of games) we have found that
    even this approach doesnt provide the whole answer in every case
    because of the commonality of run-time support that the games programs
    need. I hope that should not apply to what you are trying to do.
    
    Hoping this helps.
    Regards
    Alan T.
    
2531.7SHOGUN::JAMBU_SSkating away on the thin ice of a new dayFri Apr 04 1997 13:184
    What does getnumtasks() return.
    
		
    
2531.8.CHEFS::TREVENNOR_AA child of initFri Apr 04 1997 18:2511
    
    Do you mean, what datatype? On a Win3.11 system it returns an integer.
    On a Win95 system I think it returns a long. If you mean what does it
    tell you... it returns the number of tasks which are running in the
    system. If what your Setup program is doing is setting up some
    subsidiary tasks the number returned from GetNumTasks should increase
    when you have run Setup and it is in progress. 
    
    Regds
    Alan T.
    
2531.9suggestionXSTACY::PATTISONA rolling stone gets the wormMon Apr 07 1997 08:059
Don't know if it will be of any help, but 

	http://www.microsoft.com/kb/articles/Q129/7/96.htm

...contains an alternative.

Dave    

2531.10Worth trying by the looks of it.CHEFS::TREVENNOR_AA child of initMon Apr 07 1997 08:416
    Hmm thanks, That might be useful to me too. I'll check it out.
    
    
    Regds
    Alan T.
    
2531.11SHOGUN::JAMBU_SSkating away on the thin ice of a new dayMon Apr 07 1997 17:289
    Does it tell the number of tasks in the system as a whole irrespective
    of my setup program.  So it means the number of tasks returned 
    will vary from user to user deppending upon the number of tasks they 
    are already running.  
    
    
    the kb article does the same trick as the shell program.
    
    Suresh
2531.12I think this is what you were asking?CHEFS::TREVENNOR_AA child of initTue Apr 08 1997 06:368
    
    Yes, the number of tasks will vary according to the user's PC setup and
    what is running at the moment. However, if you snapshot the task count
    at the time you start SETUP you should then stand a good chance of
    telling when it and it's children have completed.
    
    AT
    
2531.13hmmXSTACY::PATTISONA rolling stone gets the wormTue Apr 08 1997 07:427
>    the kb article does the same trick as the shell program.

I don't think it counts the tasks on the system though.

What if your user decides to shut down some applications while
your setup program is running? (Quite a common occurrence). 

2531.14SHOGUN::JAMBU_SSkating away on the thin ice of a new dayTue Apr 08 1997 10:324
    The worksaround in .1 works ok in the debug mode (with a breakpoint)
    but does not work in runtime.  i must be missing something.  
    
    
2531.15Hmmm stranger and stranger.CHEFS::TREVENNOR_AA child of initTue Apr 08 1997 19:357
    Did you use the code as-is in .1? If not, can you post the fragment
    affected, I can't why it doesnt work at run-time? What application are
    you launching? Is it the mplayer I used, or your Setup program?
    
    Rgds
    AT
    
2531.16SHOGUN::JAMBU_SSkating away on the thin ice of a new dayWed Apr 09 1997 11:07116

This is the code I am using.  mod_use is a global returned from 
my shell command. Mod_use somehow loses the value of the instance handle 
and the next fragment of the code is called when there is no breakpoint.

When there is a breakpoint, obviously it works fine, since the code has 
broken at that point.  


I also tried the numtasks approach and numtasks changes from 2 to 3
after the setup is launched.  Once in this routine it drops to 2, while
this setup is still running and the timer signals that this program is over
and the next setup starts, which is not what I want.

 


I have to launch a few setup.exe.
------------------------------------

Sub tmrCheckForCompletion_Timer ()

    Dim RetVal%
    Dim msg As String
    Dim nl As String
    Dim response As Integer
    Dim cmdline As String
    nl = Chr$(10) & Chr$(13)
    Dim handle As Long
    Dim handle2 As Long
    '
    ' See if the current installation has completed.
    ' If it has, then start up another if more are waiting.
    ' If not, See if we need to Reboot the system
    '


handle2 = getnumtasks()
''''''''''''''''''''''
Debug.Print "mod_use = "; mod_use
Debug.Print "tasks before  = "; handle5
Debug.Print "tasks now ="; handle2



While Getmoduleusage(mod_use) > 0



'Setup app is still running, restart the timer

tmrCheckForCompletion.Interval = TimerCount

Exit Sub

Wend
  Debug.Print "event has finished"


    ' Setup app has finished
    cntInstallsDone = cntInstallsDone + 1
    
    ProductIndex = FindProdToInstall(ProductIndex)
    If ProductIndex > 0 Then
        pnlInfo.Caption = "Installing: " & ProductSet(ProductIndex).Name
        Call StartInstall(ProductIndex)
        tmrCheckForCompletion.Interval = TimerCount
        tmrCheckForCompletion.Enabled = True
    Else
        InstallsInProcess = False
        tmrCheckForCompletion.Enabled = False
        Call UpdateInfo("Installation are Complete.")
        MsgBox "Installation(s) are Complete.", vbOKOnly + vbInformation, "Installation Status"
        If RebootRequired Then
            '
            ' Perform Reboot Now?
            '
            msg = "To ensure proper application function, the system" & nl
            msg = msg & "must be rebooted." & nl & nl
            msg = msg & "Would you like the system to reboot NOW?"
            response = MsgBox(msg, vbYesNo + vbQuestion, "Installs Complete - Reboot System")
            Select Case response
                Case vbIDYes
                    Select Case Processor_Type
                        Case Intel_Processor
                            cmdline = UCase$(DefPath & "intel\IntelReb.exe")
                        Case Alpha_Processor
                            cmdline = UCase$(DefPath & "alpha\AlphaReb.exe")
                    End Select
                    RetVal% = WinExec(cmdline, 1)
                    If RetVal% < 32 Then
                        ' We have an error condition
                        Select Case RetVal%
                            Case 31
                                MsgBox "Reboot Failed - No association exists.", vbOKOnly + vbCritical, "Unable to Start " & cmdline
                            Case ERROR_FILE_NOT_FOUND
                                MsgBox "Reboot Failed - File not found.", vbOKOnly + vbCritical, "Unable to Start " & cmdline
                            Case ERROR_PATH_NOT_FOUND
                                MsgBox "Reboot Failed - Path not found.", vbOKOnly + vbCritical, "Unable to Start " & cmdline
                            Case 0
                                MsgBox "Reboot Failed - Memory or Resources exhausted.", vbOKOnly + vbCritical, "Unable to Start " & cmdline
                        End Select
                    Else
                    End If
                    Call cmdExit_Click
                Case vbIDNo
                    MsgBox "Please reboot the system at your earliest convenience.", vbOKOnly + vbInformation, "Reboot Reminder"
                    Call cmdExit_Click
            End Select
        End If
    End If

End Sub


2531.17SHOGUN::JAMBU_SSkating away on the thin ice of a new dayFri Apr 25 1997 15:323
    Anybody has any updates on this?
    
    Suresh