El servicio de Windows cambia el comportamiento de la redirección de eco/secuencia en el archivo por lotes
Frecuentes
Visto 197 equipos
3
Create a Windows batch file c:\test\first.bat:
@echo off
echo A
call second.bat < empty.txt
echo B
echo C
and two empty files c:\test\second.bat and c:\test\empty.txt (The same happens if they are not empty.)
Run first.bat. As expected the output is
A
B
C
Now, instead of running the batch file directly, create a C# command line application:
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();
}
}
}
Again, as expected the file c:\test\log.txt is created and contains
A
B
C
Now, instead of a command line application, create a Windows Service:
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()
{
}
}
}
Install and start the service (allow the required permissions to all related files). (It does not seem to matter which account (User, Local Service, Local System ...) is used for the service.)
Again the file c:\test\slog.txt is created, but now it contains:
A
echo B
B
echo C
C
¿Por qué?
(Maybe related: If there is no newline character after "echo C" in first.bat, the slog.txt contains:
A
echo B
B
more?
Why?)
1 Respuestas
1
(Solution provided in the comments. Converted to a community wiki answer. See Pregunta sin respuestas, pero problema resuelto en los comentarios (o extendido en el chat) )
@Gennadiy wrote:
Try to add processInfo.RedirectStandardInput = true;
El OP escribió:
Yes, that makes the service behave more like I expected. Any idea why? Are there any downsides to using this?
@Harry Johnston wrote:
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
Esta completo.
respondido 20 mar '17, 09:03
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c# batch-file cmd windows-services or haz tu propia pregunta.
Try to add processInfo.RedirectStandardInput = true; - Gennady
Thanks for the suggestion. Yes, that makes the service behave more like I expected. Any idea why? Are there any downsides to using this? - Peter
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
Esta completo. - Harry Johnston