Bri*_*rns 50
根据Andrew Lessard的回答,这是一个运行命令并将输出作为字符串返回的函数 -
Public Function ShellRun(sCmd As String) As String
'Run a shell command, returning the output as a string
Dim oShell As Object
Set oShell = CreateObject("WScript.Shell")
'run command
Dim oExec As Object
Dim oOutput As Object
Set oExec = oShell.Exec(sCmd)
Set oOutput = oExec.StdOut
'handle the results as they are written to and read from the StdOut object
Dim s As String
Dim sLine As String
While Not oOutput.AtEndOfStream
sLine = oOutput.ReadLine
If sLine <> "" Then s = s & sLine & vbCrLf
Wend
ShellRun = s
End Function
Run Code Online (Sandbox Code Playgroud)
用法:
MsgBox ShellRun("dir c:\")
Run Code Online (Sandbox Code Playgroud)
Ale*_* K. 20
您可以CreateProcess将应用程序重定向StdOut到管道,然后直接读取该管道; http://pastebin.com/CszKUpNS
dim resp as string
resp = redirect("cmd","/c dir")
resp = redirect("ipconfig","")
Run Code Online (Sandbox Code Playgroud)
根据主要来自布莱恩·伯恩斯(Brian Burns)的各种答案,这里是一个经过测试且功能齐全的简短版本:
Function F_shellExec(sCmd As String) As String
Dim oShell As New WshShell 'requires ref to Windows Script Host Object Model
F_shellExec = oShell.Exec(sCmd).StdOut.ReadAll
End Function
Run Code Online (Sandbox Code Playgroud)
它工作得很好而且速度很快。但是,如果输出太大(例如扫描整个 C: 驱动器sCmd = "DIR /S C:\"),ReadAll将会崩溃
所以我想出了下面的第二个解决方案,到目前为止,在这两种情况下都运行良好。请注意,第一次读取速度更快,如果崩溃,读取会从头开始,这样您就不会错过信息
Function F_shellExec2(sCmd As String) As String
'Execute Windows Shell Commands
Dim oShell As New WshShell 'requires ref to Windows Script Host Object Model
'Dim oExec As WshExec 'not needed, but in case you need the type
Dim oOutput As TextStream
Dim sReturn As String
Dim iErr As Long
'Set oExec = oShell.Exec(sCmd) 'unused step, for the type
Set oOutput = oShell.Exec(sCmd).StdOut
On Error Resume Next
sReturn = oOutput.ReadAll
iErr = Err.Number
On Error GoTo 0
If iErr <> 0 Then
sReturn = ""
While Not oOutput.AtEndOfStream
sReturn = sReturn & oOutput.ReadLine & Chr(10)
Wend
End If
F_shellExec2 = sReturn
End Function
Run Code Online (Sandbox Code Playgroud)
关于对 的引用
Windows Script Host Object Model:您将需要添加对 的引用,以便了解Windows Script Host Object Model类型WshShell(和)。 (为此,请转到VBA IDE 菜单栏中的“工具” -> “参考” 。)WshExec
根据Brian Burns 的回答,我在调用期间向可执行文件添加了传递输入(使用StdInput)。以防万一有人偶然发现并有同样的需求。
''' <summary>
''' Executes the given executable in a shell instance and returns the output produced
''' by it. If iStdInput is given, it is passed to the executable during execution.
''' Note: You must make sure to correctly enclose the executable path or any given
''' arguments in quotes (") if they contain spaces.
''' </summary>
''' <param name="iExecutablePath">
''' The full path to the executable (and its parameters). This string is passed to the
''' shell unaltered, so be sure to enclose it in quotes if it contains spaces.
''' </param>
''' <param name="iStdInput">
''' The (optional) input to pass to the executable. Default: Null
''' </param>
Public Function ExecuteAndReturnStdOutput(ByVal iExecutablePath As String, _
Optional ByVal iStdInput As String = vbNullString) _
As String
Dim strResult As String
Dim oShell As WshShell
Set oShell = New WshShell
Dim oExec As WshExec
Set oExec = oShell.Exec(iExecutablePath)
If iStdInput <> vbNullString Then
oExec.StdIn.Write iStdInput
oExec.StdIn.Close ' Close input stream to prevent deadlock
End If
strResult = oExec.StdOut.ReadAll
oExec.Terminate
ExecuteAndReturnStdOutput = strResult
End Function
Run Code Online (Sandbox Code Playgroud)
注意:您将需要添加
Windows Script Host Object Model对类型WshShell和WshExec已知的引用。
(要执行此操作,请转到VBA IDE 菜单栏中的Extras -> References。)
您可以使用以下小 C# 程序来测试来自 VBA 的调用。(如果您手边没有 Visual Studio (Express),您可以按照这些说明从一个简单的源文件快速编译它。):
using System;
class Program
{
static void Main(string[] args)
{
// Read StdIn
string inputText = Console.In.ReadToEnd();
// Convert input to upper case and write to StdOut
Console.Out.Write(inputText.ToUpper());
}
}
Run Code Online (Sandbox Code Playgroud)
在 VBA 中,您可以运行以下方法,该方法将显示一个包含“ABCDEF”的消息框:
Public Sub TestStdIn()
MsgBox ExecuteAndReturnStdOutput("C:\ConvertStdInToUpper.exe", "abcdef")
End Sub
Run Code Online (Sandbox Code Playgroud)
小智 5
Sub StdOutTest()
Dim objShell As Object
Dim objWshScriptExec As Object
Dim objStdOut As Object
Dim rline As String
Dim strline As String
Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec("c:\temp\batfile.bat")
Set objStdOut = objWshScriptExec.StdOut
While Not objStdOut.AtEndOfStream
rline = objStdOut.ReadLine
If rline <> "" Then strline = strline & vbCrLf & CStr(Now) & ":" & Chr(9) & rline
' you can handle the results as they are written to and subsequently read from the StdOut object
Wend
MsgBox strline
'batfile.bat
'ping 1.1.1.1 -n 1 -w 2000 > nul
'echo 2
'ping 1.1.1.1 -n 1 -w 2000 > nul
'echo 4
'ping 1.1.1.1 -n 1 -w 2000 > nul
'echo 6
'ping 1.1.1.1 -n 1 -w 2000 > nul
'echo 8
End Sub
Run Code Online (Sandbox Code Playgroud)
小智 5
对于那些预期回报较小的情况,这是我见过的最短的命令:
MsgBox CreateObject("WScript.Shell").Exec("C:\Windows\SysWOW64\WHOAMI.EXE /USER /FO CSV").StdOut.ReadAll
Run Code Online (Sandbox Code Playgroud)