Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPrivate Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As LongPrivate Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongConst PROCESS_QUERY_INFORMATION = &H400Const STILL_ALIVE = &H103
Private sub commandateclick () dim PID as longpid = shell ("C:/. bat ", vbnormalfocus) hprocess = OpenProcess (process_query_information, 0, pid) docall getexitcodeprocess (hprocess, exitcode) doeventsloop while exitcode = export closehandle (hprocess) msgbox (" Running ended ") end sub
The source text is as follows:
-------------------------------------------------------------------------
VB starts/ends another program (the shell waits for the program to end). In VB, the external program is often run using shell commands. However, after the external process is created, it will return to the next line of VB immediately, and cannot execute the next line of command until the end of the process, or say, it cannot know whether the process has ended. What's more, this process is half executed, and how to abort its execution is 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 OS and used to differentiate each process. This process ID (PID) it is mainly used to obtain information about the process. However, to control the process, most of them use process handle (hprocess ). The Return Value of the VB shell command is PID rather than hprocess. Therefore, we need to use the OpenProcess API to obtain the first parameter of hprocess and OpenProcess, indicates the capabilities of the obtained hprocess. For example, process_query_information enables getexitcode () to obtain the state of the process referred to by hprocess, while process_terminate means terminateprocess (hprocess ..) in other words, different parameter settings make hprocess have different permissions and capabilities. After hprocess is obtained, you can use waitforsingleobject () to wait for the hprocess status to change. That is to say, it will wait until the process indicated by hprocess is executed and the command ends, its second parameter refers to the waiting time (in milliseconds) for waitforsingleobject (). If the waiting time exceeds the specified time, the waitforsingleobject () wait is ended in timeout. If you want it to wait infinitely, 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. Sometimes 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 and pass another value until the end. If the program ends normally, exitcode = 0, otherwise, it depends on how it ends. Some people may see that the loop is loop while exitcode <> 0 elsewhere, which is a little dangerous. If we look at this process, instead of using F4 to leave Pe2, you can use the end DOS window in the top right of X to enter an infinite loop 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, in addition, 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 I force the process created by Shell to end, that is, 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 refers to the second parameter passed to getexitcodeprocess (). This is what we give at will, but it is best not to set it to 0, because 0 generally indicates a normal end. Of course, this setting will not be wrong. Of course it cannot be set to & h103. In this example, 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 and execute terminateprocess (hprocess, 3838), then you will see exitcode = 3838. However, this method is okay in Win95. In NT, you may need to change the first parameter in OpenProcess () to process_query_information or process_terminate to work. However, do not use terminateprocess () unless it is at the last point, because it is not normal to end, and has not done anything before the end of many programs, resource waste may occur. In other words, some programs may encounter problems when you run them again next time. For example, I often use MS-dos shell link to execute a process, if the MS-dos shell link does not end normally through the connection between the COM port and the big computer, we will find too opens next time we want to link it. This is an example. In addition, someone uses shell to execute. BAT file: pid = shell ("C:/AA. bat ", vbnormalfocus) but met AA. bat is over, but the MS-DOS window is still alive, you can do pid = shell ("C:/command.com/C:/AA. bat ", vbnormalfocus) is to execute command.com, while command.com specifies to execute C:/AA. BAT and automatically close all programs at the end: Private declare function OpenProcess lib "Kernel32" _ (byval dwdesiredaccess as long, byval binherithandle as long, _ byval dwprocessid as long) as longprivate declare F Unction 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 UEX Itcode 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:/tool S/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 = openpr Ocess (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 into shell when calling an external program, usually VB (a) will continue the following statement after calling, regardless of the shell program The execution is not complete. Sometimes we need to continue after the shell execution is complete. What should we do? See source process: Public declare function OpenProcess lib "Kernel32" alias "OpenProcess" (byval dwdesiredaccess as long, byval binherithandle as long, byval dwprocessid as long) as longpublic declare function implements lib "Kernel32" alias "handler" (byval hhandle as long, byval ready as long) as longpublic declare function closehandle lib "Kernel32" alias "closehandle" (byval Hob Ject as long) as longdim lngpid as long dim lngphandle as longlngpid = shell ("Notepad", vbnormalfocus) lngphandle = OpenProcess (synchronize, 0, lngpid) if lngphandle <> 0 then call waitforsingleobject (lngphandle, infinite) 'waits infinitely until the program ends call closehandle (lngphandle) end if you need to note that before the shell program is completed, your program can't do anything, please be careful for it http://bbs.office-cn.net/dispbbs.asp? Boardid = 150 & id = 7623 [laviewpbt]: Private declare function waitforsingleobject lib "Kernel32" (byval hhandle as long, byval dwmilliseconds as long) as longprivate declare function closehandle lib "Kernel32" (byval hobject as long) as longprivate declare function shellexecuteex lib "shell32.dll" alias "alias" (lpinfo as any) as long private type shellexecuteinfo cbsize as long fmask as long H WND as long lpverb as string lpfile as string lpparameters as string lpdirectory as string nshow as long hinstapp as long 'optional members lpidlist as long lpclass as string hkeyclass as long dwhotkey as long hicon_or_monitor as long hprocess as longend type private sub form_load () dim Si as shellexecuteinfo Si. cbsize = Len (SI) Si. lpverb = "open" Si. lpfile = "notepad.exe" Si. lpparameters = "" Si. Lpdirectory = "" Si. nshow = 5'sw _ show Si. fmask = & h40' see _ mask_nocloseprocess shellexecuteex Si if Si. hprocess <> 0 then waitforsingleobject Si. hprocess, & hffffff' infinite wait until the program ends closehandle Si. hprocess msgbox "is running successfully! "End ifend sub