VB6:如何执行.bat文件,但要等到它运行完毕后才能继续?

VB6:如何执行.bat文件,但要等到它运行完毕后才能继续?,vb6,batch-file,Vb6,Batch File,VB 6:如何执行.bat文件,但要等到它运行完毕后再继续?您需要在SHELLEXECUTEINFO结构中对ShellExecuteEx返回的进程句柄使用Win32 API调用和WaitForSingleObject。这是我从一个项目中提取的旧代码。这是工作100%,但我可能没有包括所有的依赖关系。您应该能够根据自己的要求进行编辑: Type SHELLEXECUTEINFO cbSize As Long fMask A

VB 6:如何执行.bat文件,但要等到它运行完毕后再继续?您需要在SHELLEXECUTEINFO结构中对ShellExecuteEx返回的进程句柄使用Win32 API调用和WaitForSingleObject。这是我从一个项目中提取的旧代码。这是工作100%,但我可能没有包括所有的依赖关系。您应该能够根据自己的要求进行编辑:

      Type SHELLEXECUTEINFO
                cbSize As Long
                fMask As Long
                hwnd As Long
                lpVerb As String
                lpFile As String
                lpParameters As String
                lpDirectory As String
                nShow As Long
                hInstApp As Long
                '  Optional fields'
                lpIDList As Long
                lpClass As String
                hkeyClass As Long
                dwHotKey As Long
                hIcon As Long
                hProcess As Long
        End Type

        Public Declare Function ShellExecuteEx Lib "shell32.dll" 
            (lpExecInfo As SHELLEXECUTEINFO) As Long

        Public Declare Function apiShellExecute Lib "shell32.dll" _
            Alias "ShellExecuteA" _
            (ByVal hwnd As Long, _
            ByVal lpOperation As String, _
            ByVal lpFile As String, _
            ByVal lpParameters As String, _
            ByVal lpDirectory As String, _
            ByVal nShowCmd As Long) _
                As Long

        Declare Function WaitForSingleObject Lib "kernel32" 
             (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long


        Public Const SEE_MASK_NOCLOSEPROCESS As Long = &H40
        Public Const SEE_MASK_FLAG_DDEWAIT As Long = &H100

        '***App Window Constants***'
        Public Const WIN_NORMAL = 1         'Open Normal'
        Public Const WIN_MAX = 2            'Open Maximized'
        Public Const WIN_MIN = 3            'Open Minimized'

        '***Error Codes***'
        Private Const ERROR_SUCCESS = 32&
        Private Const ERROR_NO_ASSOC = 31&
        Private Const ERROR_OUT_OF_MEM = 0&
        Private Const ERROR_FILE_NOT_FOUND = 2&
        Private Const ERROR_PATH_NOT_FOUND = 3&
        Private Const ERROR_BAD_FORMAT = 11&

' Returns 'True' if file was opened ...'
Public Function fHandleFile(ByVal stFile As String, _
                            ByVal lShowHow As Long, _
                            ByRef stRet As String, _
                            Optional ByVal bWaitForClose As Boolean = False) As Boolean
On Error GoTo err_Handler
    Dim lRet As Long
    Dim ret As Long
    Dim lngProcessHandle As Long
    Dim varTaskID As Variant
    Dim shInfo As SHELLEXECUTEINFO
    Dim retval As Long

    'First try ShellExecute'
    With shInfo
        .cbSize = LenB(shInfo)
        .lpFile = stFile
        .nShow = lShowHow
        If bWaitForClose Then
            .fMask = SEE_MASK_FLAG_DDEWAIT + SEE_MASK_NOCLOSEPROCESS
        End If
        .lpVerb = "open"
    End With

    Call ShellExecuteEx(shInfo)
    lRet = shInfo.hInstApp

    If lRet > ERROR_SUCCESS And bWaitForClose = True Then
        lngProcessHandle = shInfo.hProcess

        Do
            retval = WaitForSingleObject(lngProcessHandle, 0)
            DoEvents
        Loop Until retval <> 258
        ret = CloseHandle(lngProcessHandle)
    End If

    fHandleFile = (lRet > 0)

exit_handler:
    Exit Function

err_Handler:
    RaiseError Err.Number, Err.Source, Err.Description
End Function
键入SHELLEXECUTEINFO
尽可能长
fMask只要
只要
动词作为字符串
lpFile作为字符串
参数作为字符串
lpDirectory作为字符串
只要
辛斯塔普,只要
“可选字段”
lpIDList尽可能长
类作为字符串
香港国际机场
dwHotKey尽可能长
希肯只要
hProcess尽可能长
端型
公共声明函数ShellExecuteEx Lib“shell32.dll”
(lpExecInfo作为SHELLEXECUTEINFO)尽可能长
公共声明函数apiShellExecute Lib“shell32.dll”_
别名“ShellExecuteA”_
(ByVal hwnd,只要_
以字符串形式执行ByVal操作_
ByVal lpFile作为字符串_
ByVal lpParameters作为字符串_
ByVal lpDirectory作为字符串_
ByVal nShowCmd(长)_
只要
声明函数WaitForSingleObject库“kernel32”
(ByVal hHandle尽可能长,ByVal dw尽可能长)尽可能长
公共Const SEE_MASK_NOCLOSEPROCESS As Long=&H40
公共Const SEE_MASK_FLAG_DDEWAIT As Long=&H100
“***应用程序窗口常量***”
公共Const WIN_NORMAL=1“开放式NORMAL”
公共Const WIN_MAX=2“开放最大化”
公用工程温_MIN=3“开放式”
“***错误代码***”
Private Const ERROR_SUCCESS=32&
私有常量错误\u否\u关联=31&
Private Const ERROR_OUT_OF_MEM=0&
Private Const ERROR\u FILE\u NOT\u FOUND=2&
私有常量错误路径未找到=3&
私有常量错误\u错误\u格式=11&
'如果文件已打开,则返回'True'。'
公共函数fHandleFile(ByVal stFile作为字符串_
拜瓦尔·伊斯:只要_
ByRef stRet作为字符串_
可选的ByVal bWaitForClose作为布尔值=False)作为布尔值
关于错误转到错误处理程序
暗淡的lRet尽可能长
暗色尽可能长
变暗lngProcessHandle为长
Dim varTaskID作为变量
Dim shInfo作为SHELLEXECUTEINFO
暗淡的后退
“第一次尝试ShellExecute”
和信福
.cbSize=LenB(shInfo)
.lpFile=stFile
.nShow=lshow
如果等待关闭,那么
.fMask=请参阅\u掩码\u标志\u DDEWAIT+请参阅\u掩码\u NOCLOSEPROCESS
如果结束
.lpVerb=“打开”
以
调用ShellExecuteEx(shInfo)
lRet=shInfo.hInstApp
如果lRet>ERROR\u SUCCESS且bWaitForClose=True,则
lngProcessHandle=shInfo.hProcess
做
retval=WaitForSingleObject(lngProcessHandle,0)
多芬特
循环直到返回258
ret=CloseHandle(lngProcessHandle)
如果结束
fHandleFile=(lRet>0)
退出\u处理程序:
退出功能
错误处理程序:
RaiseError错误号、错误源、错误描述
端函数

类似地,使用内部Shell()函数:

Private Const INFINITE = &HFFFF
Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_QUERY_INFORMATION = &H400

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 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 Function SyncShell( _
    ByVal PathName As String, _
    ByVal WindowStyle As VbAppWinStyle) As Long
    'Shell and wait.  Return exit code result, raise an
    'exception on any error.
    Dim lngPid As Long
    Dim lngHandle As Long
    Dim lngExitCode As Long

    lngPid = Shell(PathName, WindowStyle)
    If lngPid <> 0 Then
        lngHandle = OpenProcess(SYNCHRONIZE _
                             Or PROCESS_QUERY_INFORMATION, 0, lngPid)
        If lngHandle <> 0 Then
            WaitForSingleObject lngHandle, INFINITE
            If GetExitCodeProcess(lngHandle, lngExitCode) <> 0 Then
                SyncShell = lngExitCode
                CloseHandle lngHandle
            Else
                CloseHandle lngHandle
                Err.Raise &H8004AA00, "SyncShell", _
                          "Failed to retrieve exit code, error " _
                        & CStr(Err.LastDllError)
            End If
        Else
            Err.Raise &H8004AA01, "SyncShell", _
                      "Failed to open child process"
        End If
    Else
        Err.Raise &H8004AA02, "SyncShell", _
                  "Failed to Shell child process"
    End If
End Function
Private Const INFINITE=&HFFFF
私有常量同步=&H100000
Private Const PROCESS\u QUERY\u INFORMATION=&H400
私有声明函数CloseHandle Lib“kernel32”(_
拜瓦尔·霍布特,只要)只要
私有声明函数GetExitCodeProcess Lib“kernel32”(_
ByVal HPPROCESS,只要_
lpExitCode As Long)As Long
私有声明函数openprocesslib“kernel32”(_
ByVal希望访问,只要_
ByVal bInheritHandle只要_
ByVal dwProcessId As Long)As Long
私有声明函数WaitForSingleObject库“kernel32”(_
拜瓦尔·汉德尔只要_
ByVal dw毫秒长)一样长
专用函数SyncShell(_
ByVal路径名作为字符串_
ByVal窗口样式作为VbAppWinStyle)一样长
“走开,等等。返回退出代码结果,引发
'任何错误的异常。
暗lngPid尽可能长
朦胧如长
长码
lngPid=Shell(路径名,WindowsStyle)
如果lngPid为0,则
lngHandle=OpenProcess(同步_
或进程(查询信息,0,lngPid)
如果lngHandle 0那么
WaitForSingleObject Inghandle,无限
如果GetExitCode(lngHandle,lngExitCode)为0,则
SyncShell=lngExitCode
拉手
其他的
拉手
错误:Raise&H8004AA00,“SyncShell”_
检索退出代码失败,错误_
&CStr(错误:最后一次错误)
如果结束
其他的
错误:Raise&H8004AA01,“SyncShell”_
“无法打开子进程”
如果结束
其他的
错误:Raise&H8004AA02,“SyncShell”_
“未能外壳化子进程”
如果结束
端函数

下面是一些简单的代码。请注意,它会发送消息(带有DoEvents),这样你的应用程序在等待时不会被冻结

Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Const SYNCHRONIZE = &H100000
Private Const WAIT_TIMEOUT As Long = &H102&

Private Sub RunCommandLine(sCmdLine As String)

    Dim nProcessID      As Long
    Dim hProcess        As Long
    Dim nResult         As Long

    nProcessID = Shell(sCmdLine, vbNormalNoFocus)

    If nProcessID <> 0 Then

        hProcess = OpenProcess(SYNCHRONIZE, 0, nProcessID)

        If hProcess <> 0 Then
            Do

                DoEvents
                nResult = WaitForSingleObject(hProcess, 50)

            Loop Until nResult <> WAIT_TIMEOUT Or m_bStop
            CloseHandle hProcess

        End If
    End If


End Sub
将函数OpenProcess Lib“kernel32”(ByVal dwDesiredAccess为Long,ByVal bInheritHandle为Long,ByVal dwProcessId为Long)声明为Long
将函数WaitForSingleObject库“kernel32”(ByVal hHandle长,ByVal DWM毫秒长)声明为Long
将函数CloseHandle Lib“kernel32”(ByVal hObject As Long)声明为Long
私有常量同步=&H100000
私人建筑工程