Solved

VB6 - How to wait for process to finish

Posted on 2004-05-01
12
13,748 Views
Last Modified: 2010-07-16
Hi All,

I need to write a customizable installation program which has this process sequence:

- Install MS Access runtimes (\Access\setup.exe)
- Install our program (\Ours\setup.exe)
- Install MSDE 2000 (\MSDE\setup.exe)

This is the function I use to run those setup.exe
-----------------------
Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadID As Long
End Type

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

Private Declare Function CreateProcessA Lib "Kernel32" (ByVal _
         lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
         lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
         ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
         ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
         lpStartupInfo As STARTUPINFO, lpProcessInformation As _
         PROCESS_INFORMATION) As Long

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

Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&

Public Function ExecCmd(commandline, Optional nothing1 As Variant)
    'nothing1 is included to be compatible with shell(command, windowstyle)
    Dim proc As PROCESS_INFORMATION
    Dim Start As STARTUPINFO
    Dim ReturnValue As Integer
   
    cmdline$ = commandline
    ' Initialize the STARTUPINFO structure:
    Start.cb = Len(Start)

    ' Start the shelled application:
    ReturnValue = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _
        NORMAL_PRIORITY_CLASS, 0&, 0&, Start, proc)

    ' Wait for the shelled application to finish:
    Do
        ReturnValue = WaitForSingleObject(proc.hProcess, 0)
        DoEvents
    Loop Until ReturnValue <> 258

    ReturnValue = CloseHandle(proc.hProcess)
    ExecCmd = ReturnValue
End Function
---------------
The thing is no matter I wait for single object to excute. It still does not stop. All 3 setup program just trying to run all together. Can ne1 help? Do you have any better solution for this problem?
0
Comment
Question by:NguyenHuy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 
LVL 1

Expert Comment

by:TheBaker
ID: 10968696
http://support.microsoft.com/default.aspx?scid=kb;EN-US;96844

That might help. It shows you how to wait for a process started with Shell() to finish before continuing with your own app. So if you changed your code to run with shell, then it should work. Or you may be able to adapt it if you don't want to change the way you start your programs.

TheBaker
0
 
LVL 19

Expert Comment

by:Shauli
ID: 10968763
Try this tiny little piece of software called iexpress. Click start > run > and type iexpress. It is one of the hidden candies in win2K & XP. What it does, it packes files into on exe selfextract file. So, you can tell iexpress to run installation one before the main installation, and installation three after the main installation. Check it. It might help.

S
0
 
LVL 28

Expert Comment

by:vinnyd79
ID: 10968916
Or try this shellwait function:


Private Declare Function OpenProcess Lib "Kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "Kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
Const STILL_ACTIVE = &H103
Const PROCESS_QUERY_INFORMATION = &H400

Private Function ShellWait(PathName, Optional WindowStyle As VbAppWinStyle = vbNormalFocus) As Double
Dim hProcess As Long, RetVal As Long
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, Shell(PathName, WindowStyle))
    Do
        GetExitCodeProcess hProcess, RetVal
        DoEvents: Sleep 100
    Loop While RetVal = STILL_ACTIVE
End Function

Private Sub Command1_Click()
ShellWait "\Access\setup.exe", vbNormalFocus
ShellWait "\Ours\setup.exe", vbNormalFocus
ShellWait "\MSDE\setup.exe", vbNormalFocus
End Sub
0
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

 
LVL 1

Author Comment

by:NguyenHuy
ID: 10969760
Thank you guys. I will try every method tomorrow when get back to work. Will reply shortly
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10970572
Do
        ReturnValue = WaitForSingleObject(proc.hProcess, 0)
        DoEvents
Loop Until ReturnValue <> 258

I think you need

Loop While ReturnValue <> 258

Except of this, it's better to replace second parameter of WaitForSingleObject with non-null value, like:
    ReturnValue = WaitForSingleObject(proc.hProcess, 100)

This gives more time to another process.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10970576
Oops, sorry. Ignore my post (at least, it's first part).
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10970580
I think your code is OK, but there are some processes which launch another process and exit immidiately. Program that tries to wait for such process continues - this happens, for example, when we run by such way Windows Explorer. Try this code with simple process like Notepad to see whether problem is in your code or in process itself.
0
 
LVL 26

Expert Comment

by:EDDYKT
ID: 10972558
Or

Dim wshShell
Set wshShell = CreateObject("WScript.Shell")
wshShell.Run "c:\notepad.exe", 1, true
Set wshShell = Nothing
0
 
LVL 1

Author Comment

by:NguyenHuy
ID: 10985721
Today finally I got my time to test your solution
The Baker, thanks for your suggestion. I have visited that page before posting question here. The solution works somewhere else but not for me
Shauli, thanks for the tiny little gem. I did not know that XP has a self extractor program. Unfortunately that not what Im looking for.
Vin, thanks your code does not work for me. I cant explain why but I got the same result as my code.
Alex, I think you are correct. However when I try paquet builder 2.8 shareware version, it does the job nicely. So it means that there must be a way to work around this problem. I can afford to pay $30 for paquet builder, but having total control of the setup program in my hands is better anywayz.
Please let me know if you know anything good. Im willing to try anything possible
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 11468903
PAQed, with points refunded (500)

modulo
Community Support Moderator
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

736 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question