问题: 如何编程以同步方式运行其它外部应用程序?
解答: 方法一:
'引用 Windows Script Host Object Model
Private Sub Command1_Click()
Dim x As New IWshRuntimeLibrary.IWshShell_Class
'Dim x As New IWshRuntimeLibrary.WshShell '用于 5.6 版本
Me.Enabled = False
x.Run x.ExpandEnvironmentStrings("%WinDir%") & "\notepad.exe", , True
VBA.MsgBox "执行完毕!"
x.Run x.ExpandEnvironmentStrings("%WinDir%") & "\CALC.EXE", , True
VBA.MsgBox "执行完毕!"
Me.Enabled = True
End Sub
方法二: [ltpao(啊炮) 提供]
Option Explicit
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Const SYNCHRONIZE = &H100000
Private Const INFINITE = &HFFFF ' Infinite timeout
Private Const WAIT_TIMEOUT = &H102&
Public Function ShellForWait(sAppName As String, Optional ByVal lShowWindow As VbAppWinStyle = vbMinimizedFocus, Optional ByVal lWaitTime As Long = 0) As Boolean
Dim lID As Long, lHnd As Long, lRet As Long
On Error Resume Next
lID = Shell(sAppName, lShowWindow)
If lID > 0 Then
lHnd = OpenProcess(SYNCHRONIZE, 0, lID)
If lHnd <> 0 Then
Do
lRet = WaitForSingleObject(lHnd, lWaitTime)
DoEvents
Loop While lRet = WAIT_TIMEOUT
CloseHandle lHnd
ShellForWait = True
Else
ShellForWait = False
End If
Else
ShellForWait = False
End If
End Function
Private Sub Command1_Click()
Me.Enabled = False
Command1.Enabled = False
ShellForWait "notepad.exe", , &HFFFF
Command1.Enabled = True
Me.Enabled = True
VBA.MsgBox "Finished!"
End Sub
方法三:
HOWTO: 32-Bit App Can Determine When a Shelled Process Ends (Q129796)
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q129796
解答: 方法一:
'引用 Windows Script Host Object Model
Private Sub Command1_Click()
Dim x As New IWshRuntimeLibrary.IWshShell_Class
'Dim x As New IWshRuntimeLibrary.WshShell '用于 5.6 版本
Me.Enabled = False
x.Run x.ExpandEnvironmentStrings("%WinDir%") & "\notepad.exe", , True
VBA.MsgBox "执行完毕!"
x.Run x.ExpandEnvironmentStrings("%WinDir%") & "\CALC.EXE", , True
VBA.MsgBox "执行完毕!"
Me.Enabled = True
End Sub
方法二: [ltpao(啊炮) 提供]
Option Explicit
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Const SYNCHRONIZE = &H100000
Private Const INFINITE = &HFFFF ' Infinite timeout
Private Const WAIT_TIMEOUT = &H102&
Public Function ShellForWait(sAppName As String, Optional ByVal lShowWindow As VbAppWinStyle = vbMinimizedFocus, Optional ByVal lWaitTime As Long = 0) As Boolean
Dim lID As Long, lHnd As Long, lRet As Long
On Error Resume Next
lID = Shell(sAppName, lShowWindow)
If lID > 0 Then
lHnd = OpenProcess(SYNCHRONIZE, 0, lID)
If lHnd <> 0 Then
Do
lRet = WaitForSingleObject(lHnd, lWaitTime)
DoEvents
Loop While lRet = WAIT_TIMEOUT
CloseHandle lHnd
ShellForWait = True
Else
ShellForWait = False
End If
Else
ShellForWait = False
End If
End Function
Private Sub Command1_Click()
Me.Enabled = False
Command1.Enabled = False
ShellForWait "notepad.exe", , &HFFFF
Command1.Enabled = True
Me.Enabled = True
VBA.MsgBox "Finished!"
End Sub
方法三:
HOWTO: 32-Bit App Can Determine When a Shelled Process Ends (Q129796)
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q129796
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long在判断的时候不正确,看了第二个例子也顺利通过,再次感谢