创建Windows批处理文件c:\ test \ first.bat:
@echo off
echo A
call second.bat < empty.txt
echo B
echo C
和两个空文件c:\ test \ second.bat和c:\ test \ empty.txt (如果它们不是空的,也会发生同样的情况。)
运行first.bat。正如预期的那样,输出是
A
B
C
现在,不是直接运行批处理文件,而是创建一个C#命令行应用程序:
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var processInfo = new ProcessStartInfo("cmd.exe", @"/c c:\test\first.bat");
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
var process = new Process();
process.EnableRaisingEvents = true;
var log = new BlockingCollection<string>();
process.OutputDataReceived += (sender, e) => log.Add(e.Data);
process.Exited += (sender, e) =>
{
process.Dispose();
File.WriteAllText(@"c:\test\log.txt", string.Join("\n", log));
};
process.StartInfo = processInfo;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
}
}
同样,正如预期的那样创建了文件c:\ test \ log.txt并包含
A
B
C
现在,不是命令行应用程序,而是创建Windows服务:
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
this.CanStop = true;
}
protected override void OnStart(string[] args)
{
var processInfo = new ProcessStartInfo("cmd.exe", @"/c c:\test\first.bat");
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
var process = new Process();
process.EnableRaisingEvents = true;
var log = new BlockingCollection<string>();
process.OutputDataReceived += (sender, e) => log.Add(e.Data);
process.Exited += (sender, e) =>
{
process.Dispose();
File.WriteAllText(@"c:\test\slog.txt", string.Join("\n", log));
};
process.StartInfo = processInfo;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
protected override void OnStop()
{
}
}
}
安装并启动服务(允许所有相关文件所需的权限)。 (这个服务使用哪个帐户(用户,本地服务,本地系统......)似乎并不重要。)
再次创建文件c:\ test \ slog.txt,但现在它包含:
A
echo B
B
echo C
C
为什么?
(也许相关:如果&#34之后没有换行符; echo C&#34;在first.bat中,slog.txt包含:
A
echo B
B
more?
为什么?)
答案 0 :(得分:1)
(评论中提供的解决方案。转换为社区维基答案。请参阅Question with no answers, but issue solved in the comments (or extended in chat))
@Gennadiy写道:
OP写道:尝试添加processInfo.RedirectStandardInput = true;
是的,这使得服务的行为更像我的预期。知道为什么吗?使用它有什么缺点吗?
@Harry Johnston写道:
当批处理器没有有效的标准输入流时,看起来会遇到麻烦。我想象一旦重定向到
empty.txt
完成后,它尝试将标准输入句柄设置回原始(无效)值时会发生根本问题。