In VB, the external program is often run using shell commands. However, after creating the external process, it immediately
It will return to the next line of VB program and cannot execute the next line of command until the process ends,
Or, you cannot know whether the process has ended. What's more, if the process is half executed?
Abort its execution and so on. These are not controlled by shell commands. Therefore, we need to complete the API help.
.
The first question is how to wait until the process created by the Shell ends before running the VB program.
The first thing to know is that each process has a unique processid, which is defined by the operating system and used
This process ID (PID) can be used to obtain the corresponding process.
However, the process is mostly controlled by Process Handle (hprocess ). VB
The Return Value of the shell command is PID rather than hprocess, so we need to use the OpenProcess API
Obtain the first parameter of hprocess and OpenProcess (), which indicates the obtained hprocess
Capability, as process_query_information means that getexitcode () can get the hprocess
And process_terminate is to make terminateprocess (hprocess ..)
That is to say, different parameter settings make hprocess have the permissions and capabilities
Different. After obtaining hprocess, you can use waitforsingleobject () to wait for the hprocess status
Change, that is, it will wait until the process indicated by hprocess is executed and the command ends.
The second parameter indicates the waiting time (in milliseconds) of waitforsingleobject)
If the specified time is exceeded, the waitforsingleobject () wait will end with timeout. If you want it
Set it to infin99ve.
PID = shell ("C:/tools/spe3/pe2.exe", vbnormalfocus)
Hprocess = OpenProcess (process_query_information, 0, pid)
Exitevent = waitforsingleobject (hprocess, infin99ve)
Call closehandle (hprocess)
At the previous meeting, the subsequent VB commands will not be executed until the process of the shell command create is complete. Yes
I think it will wait too long, so there is a second solution: wait until the process ends and then notify VB, that is
: Set a public variable (isdone). When it becomes true, the process created by the table shell is closed.
. When the process is still being executed, getexitcodeprocess will pass & h103 to the second parameter
If the program ends normally, exitcode = 0. Otherwise, you have to check how it works.
It's over. Some people may see loop while exitcode <> 0 elsewhere.
It is a little dangerous. In this case, you don't use F4 to leave Pe2, but end with X in the upper right.
DOS window will enter infinite Loops because the exitcode value is never 0.
Dim PID as long
PID = shell ("C:/tools/spe3/pe2.exe", vbnormalfocus)
Hprocess = OpenProcess (process_query_information, 0, pid)
Isdone = false
Do
Call getexitcodeprocess (hprocess, exitcode)
Debug. Print exitcode
Doevents
Loop while exitcode = still_alive
Call closehandle (hprocess)
Isdone = true
In addition, if the program created by your shell has a window and is immediately focused, it can be used separately
Dim PID as long
Dim hwnd5 as long
PID = shell ("C:/tools/spe3/pe2.exe", vbnormalfocus)
Hwnd5 = getforegroundwindow ()
Isdone = false
Do While iswindow (hwnd5)
Doevents
Loop
Isdone = true
How can we force the process created by Shell to end?
Dim AA as long
If hprocess <> 0 then
AA = terminateprocess (hprocess, 3838)
End if
Hprocess is the Process Handle obtained in the previous example. 3838 indicates that
The second parameter in getexitcodeprocess (). This parameter is random, but it is better not to be 0, because
0 generally indicates that the process ends normally. Of course, this setting will not be wrong. Of course it cannot be set & h103. Here is an example.
See if the program is located in the following Loop
Do
Call getexitcodeprocess (hprocess, exitcode)
Debug. Print exitcode
Doevents
Loop while exitcode = still_alive
Debug. Print exitcode
When terminateprocess (hprocess, 3838) is executed, exitcode = 3838 is displayed. However
However, this method is okay in Win95. In NT, you may need to calculate the first parameter in OpenProcess ()
Change to process_query_information or process_terminate to work. However
Do not use terminateprocess () unless it is at the last moment.
Before the end of many programs, you have not done anything, which may result in a waste of resources.
There may be problems when running some programs. For example, I often use the MS-dos shell Link Method to execute a process.
If the MS-dos shell link does not end normally
If you want to link, you will find too release opens. This is an example.
In addition, someone uses shell to execute the. BAT file, that is:
PID = shell ("C:/AA. Bat", vbnormalfocus)
However, the AA. bat is over, but the MS-DOS window is still alive. You can do it in the following way:
PID = shell ("C:/command.com/C:/AA. Bat", vbnormalfocus)
That is to execute command.com, while command.com specifies to execute C:/AA. BAT and automatically close at the end.
All programs are as follows:
Private declare function OpenProcess lib "Kernel32 "_
(Byval dwdesiredaccess as long, byval binherithandle as long ,_
Byval dwprocessid as long) as long
Private declare function waitforsingleobject lib "Kernel32 "_
(Byval hhandle as long, byval dwmilliseconds as long) as long
Private declare function closehandle lib "Kernel32 "_
(Byval hobject as long) as long
Private declare function getexitcodeprocess lib "Kernel32 "_
(Byval hprocess as long, lpexitcode as long) as long
Private declare function terminateprocess lib "Kernel32 "_
(Byval hprocess as long, byval uexitcode as long) as long
Private declare function getforegroundwindow lib "USER32" () as long
Private declare function iswindow lib "USER32 "_
(Byval hwnd as long) as long
Const process_query_information = & H400
Const still_alive = & h103
Const infin99ve = & hffff
Private exitcode as long
Private hprocess as long
Private isdone as long
Private sub commandementclick ()
Dim PID as long
PID = shell ("C:/tools/SPE/pe2.exe", vbnormalfocus)
Hprocess = OpenProcess (process_query_information, 0, pid)
Isdone = false
Do
Call getexitcodeprocess (hprocess, exitcode)
Debug. Print exitcode
Doevents
Loop while exitcode = still_alive
Call closehandle (hprocess)
Isdone = true
End sub
Private sub command2_click ()
Dim PID as long
Dim exitevent as long
PID = shell ("C:/tools/spe3/pe2.exe", vbnormalfocus)
Hprocess = OpenProcess (process_query_information, 0, pid)
Exitevent = waitforsingleobject (hprocess, infin99ve)
Call closehandle (hprocess)
End sub
Private sub command3_click ()
Dim AA as long
If hprocess <> 0 then
AA = terminateprocess (hprocess, 3838)
End if
End sub
Private sub command4_click ()
Dim PID as long
Dim hwnd5 as long
PID = shell ("C:/tools/spe3/pe2.exe", vbnormalfocus)
Hwnd5 = getforegroundwindow ()
Isdone = false
Do While iswindow (hwnd5)
Doevents
Loop
Isdone = true
End sub
Private sub command5_click ()
Dim PID as long
'Pid = shell ("C:/Windows/command/xcopy C:/AA. bat a:", vbhide)
PID = shell ("C:/command.com/C:/AA. Bat", vbnormalfocus)
End sub