知识大全 VB Shell调用后 等待程序运行结束

Posted 结束

篇首语:绳锯木断,水滴石穿。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 VB Shell调用后 等待程序运行结束相关的知识,希望对你有一定的参考价值。

VB Shell调用后 等待程序运行结束  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  

  Private Declare Function OpenProcess Lib kernel (ByVal dwDesiredAccess As Long ByVal bInheritHandle As Long ByVal dwProcessId As Long) As Long

  Private Declare Function GetExitCodeProcess Lib kernel (ByVal hProcess As Long lpExitCode As Long) As Long

  Private Declare Function CloseHandle Lib kernel (ByVal hObject As Long) As Long

  Const PROCESS_QUERY_INFORMATION = &H

  Const STILL_ALIVE = &H

  Private Sub Command _Click()

  Dim pid As Long

  pid = Shell( c:\\a bat vbNormalFocus)

  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION pid)

  Do

  Call GetExitCodeProcess(hProcess ExitCode)

  DoEvents

  Loop While ExitCode = STILL_ALIVE

  Call CloseHandle(hProcess)

  MsgBox ( 运行结束 )

  End Sub

  摘自原文如下           VB启动/结束另一程序(Shell 等待程序运行结束)   VB 中 常以Shell指令来执行外部程式 然而它在Create该外部process 后 立刻就会回到vb 的下一行程式 无法做到等待该Process结束时 才执行下一行指令 或是说 无法得知该Process是否已结束 甚者 该Process执行到一半 又该如何中止其执行等等 这些都不是Shell指令所能控制的 因此我们需使API的帮助来完成  

  第一个问题 如何等待shell所Create的process结束后才往后执行vb的程式    首先要知道的是 每个Process有唯一的一个ProcessID 这是OS给定的 用来区别每个 Process 这个Process ID(PID)主要可用来取得该Process相对应的一些资讯 然而要对该Process的控制 却大多透过 Process Handle(hProcess) VB Shell指令的传回值是PID 而非hProcess 所以我们需透过OpenProcess这个API来取得 hProcess而OpenProcess()的第一个三数 指的是所取得的hProcess所具有的能力 像 PROCESS_QUERY_INFORMATION 便是让GetExitCode()可取得hProcess所指的process之状态 而PROCESS_TERMINATE 便是让TerminateProcess(hProcess……)   的指令能够生效 也就是说 不同三数设定 使hProcess所具有的权限 能力有所不同 取得 hProcess后便可以使用WaitForSingleObject()来等待hProcess状态的改变 也就是说 它会等待 hProcess所指的process执行完 这个指令才结束 它第二个三数所指的是 WaitForSingleObject()所要等待的时间(in milliseconds )    如果超过所指的时间 就TimeOut而结束WaitForSingleObject()的等待 若要它无限的等下去 就设定为INFIN vE            pid = Shell( C:\\tools\\spe \\pe exe vbNormalFocus)        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION pid)        ExitEvent = WaitForSingleObject(hProcess INFIN vE)        Call CloseHandle(hProcess)

  上例会无限等待shell指令create之process结束后 才再做后面的vb指令 有时觉得那会等太久 所以有第二个解决方式 等process结束时再通知vb 就好 即 设定一个公用变数(isDone) 当它变成True时代表Shell所Create的Process已结束 当Process还在执行时 GetExitCodeProcess会传&H 给其第二个三数 直到结束时才传另外的数值 如果程式正常结束 那Exitcode = 否则就得看它如何结束了 或许有人在其他地方看到 loop的地方是Loop while Exitcode <> 那有一点危险 如果以这程子来看 您不是用F 来离开pe 而是用右上方 X 的结束dos window那麽 会因为ExitCode的值永远不会是 而进入无穷的回圈

            Dim pid As Long        pid = Shell( C:\\tools\\spe \\pe exe vbNormalFocus)        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION pid)        isDone = False        Do        Call GetExitCodeProcess(hProcess ExitCode)        Debug Print ExitCode        DoEvents        Loop While ExitCode = STILL_ALIVE        Call CloseHandle(hProcess)        isDone = True

  另外 如果您的shell所Create的程式 有视窗且为立刻Focus者 可另外用以        下的方式

      Dim pid As Long        Dim hwnd As Long        pid = Shell( c:\\tools\\spe \\pe exe vbNormalFocus)        hwnd = GetForegroundWindow()        isDone = False        Do While IsWindow(hwnd )        DoEvents        Loop        isDone = True

  而如何强迫shell所Create的process结束呢 那便是         Dim aa As Long        If hProcess <> Then        aa = TerminateProcess(hProcess )        End If

  hProcess便是先前的例子中所取得的那个Process Handle 所指的是传给GetExitCodeProcess()中的第二三数 这是我们任意给的 但最好不要是 因为 一般是代表正常结束 当然这样设也不会有错 当然不可设&H 以这个例子来看 如果程式正处于以下的LOOP          Do        Call GetExitCodeProcess(hProcess ExitCode)        Debug Print ExitCode        DoEvents        Loop While ExitCode = STILL_ALIVE        Debug print ExitCode   而执行了 TerminateProcess(hProcess )那会看到ExitCode = 然而 这个方式在win 没问题 在NT中 可能您要在OpenProcess()的第一个三数要更改成 PROCESS_QUERY_INFORMATION Or PROCESS_TERMINATE 这样才能Work 不过良心的建议 非到最后关头 不要使用TerminateProcess() 因不正常的结束 往往许多程式结束前所要做的事都没有做 可能造成Resource的浪费 甚者 下次再执行某些程式时会有问题 例如 本人常使用MS dos Shell Link 的方式执行一程式 透过Com port与大电脑的联结 如果Ms dos Shell Link 不正常结束 下次再想Link时 会发现too Many Opens 这便是一例    另外 有人使用Shell来执行 bat档 即 pid = Shell( c \\aa bat vbNormalFocus)   可是却遇上aa bat结束了 但ms dos的Window却仍活着 那可以用以下的方式来做pid = Shell( c \\ /c c \\aa bat vbNormalFocus)   那是执行 而指定执行c \\aa bat 而且结束时自动Close所有程式如下          Private Declare Function OpenProcess Lib kernel _        (ByVal dwDesiredAccess As Long ByVal bInheritHandle As Long _        ByVal dwProcessId As Long) As Long

  Private Declare Function WaitForSingleObject Lib kernel _        (ByVal hHandle As Long ByVal dwMilliseconds As Long) As Long        Private Declare Function CloseHandle Lib kernel _        (ByVal hObject As Long) As Long        Private Declare Function GetExitCodeProcess Lib kernel _        (ByVal hProcess As Long lpExitCode As Long) As Long        Private Declare Function TerminateProcess Lib kernel _        (ByVal hProcess As Long ByVal uExitCode As Long) As Long        Private Declare Function GetForegroundWindow Lib user () As Long        Private Declare Function IsWindow Lib user _        (ByVal hwnd As Long) As Long

  Const PROCESS_QUERY_INFORMATION = &H         Const STILL_ALIVE = &H         Const INFIN vE = &HFFFF

  Private ExitCode As Long        Private hProcess As Long        Private isDone As Long        Private Sub Command _Click()        Dim pid As Long        pid = Shell( C:\\tools\\spe\\pe exe vbNormalFocus)        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION 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 Command _Click()        Dim pid As Long        Dim ExitEvent As Long        pid = Shell( C:\\tools\\spe \\pe exe vbNormalFocus)        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION pid)        ExitEvent = WaitForSingleObject(hProcess INFIN vE)        Call CloseHandle(hProcess)        End Sub

  Private Sub Command _Click()        Dim aa As Long        If hProcess <> Then        aa = TerminateProcess(hProcess )        End If

  End Sub

  Private Sub Command _Click()        Dim pid As Long        Dim hwnd As Long        pid = Shell( c:\\tools\\spe \\pe exe vbNormalFocus)        hwnd = GetForegroundWindow()        isDone = False        Do While IsWindow(hwnd )        DoEvents        Loop        isDone = True        End Sub

  Private Sub Command _Click()        Dim pid As Long        pid = Shell( c:\\windows\\mand\\xcopy c:\\aa bat a: vbHide)        pid = Shell( c:\\ /c c:\\aa bat vbNormalFocus)        End Sub

        

  「Modest」

  在使用shell后 如何等待此程序完成后 程序才继续执行 我们使用 shell 调用一个外部程序的时候 通常 vb(a) 会在调用之后继续下面的语句 而不管此 shell 程序执行完成没有 有时我们需要在此 shell 执行完成之后才继续 又当如何呢?   请看源程

            Public Declare Function OpenProcess Lib kernel Alias OpenProcess (ByVal dwDesiredAccess As Long ByVal bInheritHandle As Long ByVal dwProcessId As Long) As Long        Public Declare Function WaitForSingleObject Lib kernel Alias WaitForSingleObject (ByVal hHandle As Long ByVal dwMilliseconds As Long) As Long        Public Declare Function CloseHandle Lib kernel Alias CloseHandle (ByVal hObject As Long) As Long        Dim lngPId As Long        Dim lngPHandle As Long        lngPId = Shell( Notepad vbNormalFocus)        lngPHandle = OpenProcess(SYNCHRONIZE lngpId)        If lngPHandle <> Then            Call WaitForSingleObject(lngPHandle INFINITE) 无限等待 直到程式结束            Call CloseHandle(lngPHandle)        End If

  需要注意的是 在 shell 程序未完成前 你的程序不能做任何事 请小心为之

  ?boardid= &ID=

  【laviewpbt】:          Private Declare Function WaitForSingleObject Lib kernel (ByVal hHandle As Long ByVal dwMilliseconds As Long) As Long        Private Declare Function CloseHandle Lib kernel (ByVal hObject As Long) As Long        Private Declare Function ShellExecuteEx Lib shell dll Alias ShellExecuteExA (lpInfo As Any) As Long

  Private 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  members               lpIDList  As Long               lpClass    As String               eyClass  As Long               dwHotKey  As Long               hIcon_OR_Monitor  As Long               hProcess  As Long        End 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 =             SW_SHOW            si fMask = &H       SEE_MASK_NOCLOSEPROCESS            ShellExecuteEx si            If si hProcess <> Then                WaitForSingleObject si hProcess &HFFFFFFFF        无限等待   直到程式结束                CloseHandle si hProcess                MsgBox 程序运行完毕!             End If        End Sub

cha138/Article/program/net/201311/11359

相关参考

知识大全 使用VB调用Oracle程序包内的存储过程返回结果集

使用VB调用Oracle程序包内的存储过程返回结果集  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 以在ASP环境下调用的运行CMD命令的VB组件

以在ASP环境下调用的运行CMD命令的VB组件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  有

知识大全 VB对注册表操作程序开机时运行

VB对注册表操作程序开机时运行  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!我们可以看到一些程序在

知识大全 使用VB.Net查找程序的前一个运行结果

使用VB.Net查找程序的前一个运行结果  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  可以从获

知识大全 jsp如何调用linux shell

  经常碰到运营部门人要清缓存而缓存一直存在问题老在电脑面前处理也不是个办法想了个方法通过访问一个jsp页面自动清缓存    <%@pagelanguage="java"im

知识大全 VB动态调用外部函数的方法

VB动态调用外部函数的方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  VB可以用Declar

知识大全 c#调用外部程序

  //本来看似非常简单的程序是一个界面左边一个提示有个checkbox提示用户我知道了请不要再显示右边是运行QQ的一个按钮但是弄的时候弄了四个小时左右经常是调试的时候是对的但是有的时候点了按钮过后没

知识大全 VB动态调用自己的ActiveX DLL

VB动态调用自己的ActiveXDLL  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &

知识大全 VB.NET编程中调用Windows API

VB.NET编程中调用WindowsAPI  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!Windo

知识大全 VB.Net调用存储过程并得到返回值

VB.Net调用存储过程并得到返回值  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  //存储过程