J
JohEble
Guest
Hi everybody,
I wrote a program that copys a directory from on PC into all other PCs in this LAN. Since the files are huge, I wrote it with a different thread. This is the most crucial part of the program (copy to one PC only):
private void StartCommand(string cmd, string cmdArgs = "")
{
output.Clear();
error.Clear();
using (var p = new Process())
{
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = @"/c xcopy D:\SourceDir \\pc-name\D$\DestName /k/r/e/i/s/c/h/f/o/x/y";
p.StartInfo.RedirectStandardError = true;
// P.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
{
p.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(e.Data);
// UpdateRtbMethod(Color.Red, e.Data);
}
};
p.OutputDataReceived += (sender, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
output.AppendLine(e.Data);
// UpdateRtbMethod(Color.Green, e.Data);
}
};
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
int timeout = 1000000;
if ((p.WaitForExit(timeout)) && (outputWaitHandle.WaitOne(/*timeout*/)) && errorWaitHandle.WaitOne(/*timeout*/))
{
// Process completed. Check process.ExitCode here.
if (output.Length > 0)
OnCommandFinished(true, output.ToString());
else if (error.Length > 0)
{
OnCommandFinished(false, error.ToString());
}
else
{
OnCommandFinished(false, "Unspecified error");
}
}
else
{
// Timed out.
OnCommandFinished(false, "The Command process timed out");
}
....
Unfortunately, I never got this to work. Also, I don't even get an error message since the Data part in the DataErrorReceived event is always null. Of couse, it works if I execute the xcopy command in a console. I guess it is because of some text formatting/escaping in the Arguments property. I have actually tried to integrate the xcopy command and the options in a batch file, calling the batch file from the above code, but all get's worse: I don't get any message anymore. It took me days to write this program, but then I tried it with Python where I used subprocess:
...
#
DestLanPaths = [r'\\' + x + r'\d$\DestDir' for x in AllTargetComputerNames]
# print(SourceLanPath)
# print(DestLanPaths)
for destLanPath in DestLanPaths :
subprocess.call(['xcopy', SourceLanPath, destLanPath, args])
And the Python program worked more or less at once! I guess that the Python subprocess.call method handles the different arguments of xcopy much better than the C# version. Any ideas why the c# version doesn't work? Did I do something wrong in the C# code?
Best regards
Johannes
Continue reading...
I wrote a program that copys a directory from on PC into all other PCs in this LAN. Since the files are huge, I wrote it with a different thread. This is the most crucial part of the program (copy to one PC only):
private void StartCommand(string cmd, string cmdArgs = "")
{
output.Clear();
error.Clear();
using (var p = new Process())
{
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = @"/c xcopy D:\SourceDir \\pc-name\D$\DestName /k/r/e/i/s/c/h/f/o/x/y";
p.StartInfo.RedirectStandardError = true;
// P.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
{
p.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(e.Data);
// UpdateRtbMethod(Color.Red, e.Data);
}
};
p.OutputDataReceived += (sender, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
output.AppendLine(e.Data);
// UpdateRtbMethod(Color.Green, e.Data);
}
};
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
int timeout = 1000000;
if ((p.WaitForExit(timeout)) && (outputWaitHandle.WaitOne(/*timeout*/)) && errorWaitHandle.WaitOne(/*timeout*/))
{
// Process completed. Check process.ExitCode here.
if (output.Length > 0)
OnCommandFinished(true, output.ToString());
else if (error.Length > 0)
{
OnCommandFinished(false, error.ToString());
}
else
{
OnCommandFinished(false, "Unspecified error");
}
}
else
{
// Timed out.
OnCommandFinished(false, "The Command process timed out");
}
....
Unfortunately, I never got this to work. Also, I don't even get an error message since the Data part in the DataErrorReceived event is always null. Of couse, it works if I execute the xcopy command in a console. I guess it is because of some text formatting/escaping in the Arguments property. I have actually tried to integrate the xcopy command and the options in a batch file, calling the batch file from the above code, but all get's worse: I don't get any message anymore. It took me days to write this program, but then I tried it with Python where I used subprocess:
...
#
DestLanPaths = [r'\\' + x + r'\d$\DestDir' for x in AllTargetComputerNames]
# print(SourceLanPath)
# print(DestLanPaths)
for destLanPath in DestLanPaths :
subprocess.call(['xcopy', SourceLanPath, destLanPath, args])
And the Python program worked more or less at once! I guess that the Python subprocess.call method handles the different arguments of xcopy much better than the C# version. Any ideas why the c# version doesn't work? Did I do something wrong in the C# code?
Best regards
Johannes
Continue reading...