我想在任务队列中执行外部程序,以对我的数据执行一些检查。因此,我启动一个外部进程,通过StandardInput为数据提供数据并读取ExitCode(Errorlevel)以查看是否满足要求。
在具体方案中,我想使用find.exe
命令搜索数据文件中的文本。如果在文件中找到文本,它应该返回0。根据find.exe-help,find.exe "Foo"
应该从StandardInput读取并搜索字符串" Foo"。
我没有得到以下内容:当我只重定向InputStream并启动进程时,find.exe会立即返回ExitCode 1(表示找不到字符串或找不到输入文件)。如果我还重定向OutputStream,一切似乎都可以正常工作。
我还使用sort.exe
命令进行了测试(如.NET帮助中的示例所示),一切正常,但没有重定向OutputStream。
这是我的简化代码(VB.net with .NET3.5SP1):
Dim inputFilename As String = "D:\Temp\names.txt"
Dim outputFilename As String = "D:\Temp\namefind.out" '* set to Nothing for malbehavior
Dim psi As New ProcessStartInfo("FIND.EXE", """Foo""")
psi.UseShellExecute = False
psi.ErrorDialog = False
Dim isr As StreamReader = Nothing, osw As StreamWriter = Nothing
If (inputFilename IsNot Nothing) Then isr = New StreamReader(inputFilename, True) : psi.RedirectStandardInput = True
If (outputFilename IsNot Nothing) Then osw = New StreamWriter(outputFilename, False) : psi.RedirectStandardOutput = True
Using p As Process = Process.Start(psi)
If isr IsNot Nothing Then _
ThreadPool.QueueUserWorkItem(Sub()
Dim buf(2 ^ 13) As Char, cnt As Integer, pin As StreamWriter = p.StandardInput
Do : cnt = isr.ReadBlock(buf, 0, 2 ^ 13) : pin.Write(buf, 0, cnt) : Loop While cnt > 0
pin.Close() : isr.Close()
End Sub)
Dim oswCnt As Long = 0
If osw IsNot Nothing Then _
ThreadPool.QueueUserWorkItem(Sub()
Dim buf(2 ^ 13) As Char, cnt As Integer, pout As StreamReader = p.StandardOutput
Do : cnt = pout.ReadBlock(buf, 0, 2 ^ 13) : osw.Write(buf, 0, cnt) : oswCnt += cnt : Loop While cnt > 0
osw.Close() : pout.Close()
End Sub)
Dim wasExit As Boolean = p.WaitForExit(10000)
End Using
要重现错误的行为,请使用
Dim outputFilename As String = Nothing
在上面的代码中(第2行)。
我在重定向部分遗漏了什么吗?为什么简单的仅输入重定向与sort.exe
一起使用,而不与find.exe
一起使用?代码应该在自动化环境中工作,所以我需要确保每次至少代码运行相同。此外,其他用户应能够配置自定义队列。一般建议重定向Input-和OutputStreams会有帮助吗?