将输入从 Excel VBA 重定向到可执行文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1860563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 11:05:02  来源:igfitidea点击:

Redirecting input to an executable from Excel VBA

excel-vbavbaredirectexcel

提问by Jean-Fran?ois Corbett

How do you redirect input to an executable from inside VBA? Specifically, why does the code below not work?

如何从 VBA 内部将输入重定向到可执行文件?具体来说,为什么下面的代码不起作用?

ChDir theRightDirectory
Set WshShell = VBA.CreateObject("WScript.Shell") 
WshShell.Run "runme < start.txt", 1, True

Or

或者

RetVal = Shell("runme < start.txt", vbNormalFocus)  

runme.exedoes start up all right, but the input is not redirected and has to be type in manually in the command window. Also tried:

runme.exe确实启动正常,但输入没有重定向,必须在命令窗口中手动输入。还试过:

RetVal = Shell("type start.txt | runme.exe", vbNormalFocus)

Piping the output of type start.txtinto runme.exejust plain returns a “file not found” error.

将 的输出管道type start.txt化为runme.exe简单的返回“找不到文件”错误。

Yet when I type those various commands directly at the command line, they all work.

然而,当我直接在命令行键入这些不同的命令时,它们都可以工作。

回答by Andy West

Execute the command this way:

以这种方式执行命令:

WshShell.Run "%COMSPEC% /C runme < start.txt", 1, True

That way it will run it through the command line interpreter.

这样它将通过命令行解释器运行它。

回答by Jean-Fran?ois Corbett

I've been made aware of this solution: No need to write the input to start.txt; input can just be fed directly to the input stream. (My question should have made clear that this is also an option.) A bonus is that the user can get feedback from the output stream.

我已经知道这个解决方案:无需将输入写入 start.txt;输入可以直接输入到输入流中。(我的问题应该明确指出这也是一个选项。)一个好处是用户可以从输出流中获得反馈。

Set WshShell = VBA.CreateObject("WScript.Shell")
WshShell.CurrentDirectory = theRightDirectory
Set oExec = WshShell.exec("runme.exe")

' Write to the input stream
oExec.StdIn.Write "some input for the first prompt" & vbCrLf & _
                  "some more input" & vbCrLf 

' The output stream can be shown to the user, e.g.
sOutput = oExec.StdOut.ReadAll()
MsgBox (sOutput)

回答by Peter Morrison

I'll answer a more general part of your question. You asked:

我会回答你问题的更一般的部分。你问:

Specifically, why does the code below not work?

WshShell.Run "runme < start.txt", 1, True

具体来说,为什么下面的代码不起作用?

WshShell.Run "runme < start.txt", 1, True

The reason the code does not work as you expect is because the shell of WScript.Shell is not the same as the shell of cmd.exe. In particular, it does not do redirects or pipes.

代码没有按预期工作的原因是 WScript.Shell 的外壳与 cmd.exe 的外壳不同。特别是,它不做重定向或管道

If you were able to debug the runme process you would see that it has been passed two arguments, <and start.txt

如果您能够调试 runme 进程,您会看到它已经传递了两个参数,<并且start.txt

As previously answered, there are two ways to fix this:

如前所述,有两种方法可以解决此问题:

  • feed the WScript.Shell StdIn directly and remove your redirect

    set oExec = WshShell.exec(cmdLine)
    oExec.StdIn.Write "some input for the first prompt" & vbCrLf

  • run the DOS shell instead of runme, let it interpret the rest of the commandline, including the redirect

    WshShell.Run "%COMSPEC% /C runme < start.txt", 1, True

  • 直接提供 WScript.Shell StdIn 并删除您的重定向

    set oExec = WshShell.exec(cmdLine)
    oExec.StdIn.Write "some input for the first prompt" & vbCrLf

  • 运行 DOS shell 而不是 runme,让它解释命令行的其余部分,包括重定向

    WshShell.Run "%COMSPEC% /C runme < start.txt", 1, True

回答by Raj More

You are probably shelling out to a different folder than you expect.

您可能正在使用与您预期不同的文件夹。

You may have to change directory using CHDIRto the appropriate folder, or qualify your file names using the entire or relative path.

您可能必须使用CHDIR适当的文件夹更改目录,或使用完整或相对路径限定您的文件名。