gpt4 book ai didi

c# - Windows 服务更改批处理文件中回显/流重定向的行为

转载 作者:行者123 更新时间:2023-11-30 17:47:59 25 4
gpt4 key购买 nike

创建 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(如果它们不为空,也会发生同样的情况。)

先运行.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()
{
}
}
}

安装并启动服务(允许对所有相关文件授予所需的权限)。(使用哪个帐户(User、Local Service、Local System ...)似乎并不重要。)

再次创建文件 c:\test\slog.txt,但现在它包含:

A
echo B
B
echo C
C

为什么?


(可能相关:如果first.bat中“echo C”后没有换行符,则slog.txt包含:

A
echo B
B
more?

为什么?)

最佳答案

(评论中提供的解决方案。转换为社区维基答案。参见 Question with no answers, but issue solved in the comments (or extended in chat))

@Gennadiy 写道:

Try to add processInfo.RedirectStandardInput = true;

OP 写道:

Yes, that makes the service behave more like I expected. Any idea why? Are there any downsides to using this?

@Harry Johnston 写道:

Looks like the batch processor runs into trouble when it doesn't have a valid standard input stream. I imagine the underlying problem occurs when it tries to set the standard input handle back to the original (invalid) value once the redirection to empty.txt is complete.

关于c# - Windows 服务更改批处理文件中回显/流重定向的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23912484/

25 4 0