问题描述
大家好,
我写了一个程序,将PC上的目录复制到该局域网中的所有其他PC上。由于文件很大,我用不同的线程编写了它。这是该计划中最重要的部分(仅限于一台PC):
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();
使用(var p = new Process())
{
p.StartInfo.FileName = QUOT; cmd.exe的英寸;
 
         &NBSP ;      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;
                使用(的AutoResetEvent outputWaitHandle =新的AutoResetEvent(假))
               使用(的AutoResetEvent errorWaitHandle =新的AutoResetEvent(假))
                {
                    p.ErrorDataReceived + =(发件人,E)=>
              &NBSP ;     {
                    &NBSP ;  如果(e.Data == NULL)
                &NBSP ;       {
                    &NBSP ;       errorWaitHandle.Set();
                         }
                    &NBSP ;  否则
                    &NBSP ;   {
                    &NBSP ;       error.AppendLine(e.Data);
                &NBSP ;           // UpdateRtbMethod(Color.Red,e.Data);
              &NBSP ;         }
                    }
    p.OutputDataReceived + =(发件人,E)=>
              &NBSP ;     {
                    &NBSP ;  如果(e.Data == NULL)
                &NBSP ;       {
                    &NBSP ;       outputWaitHandle.Set();
                         }
                    &NBSP ;  否则
                    &NBSP ;   {
                    &NBSP ;       output.AppendLine(e.Data);
                &NBSP ;           // UpdateRtbMethod(Color.Green,e.Data);
              &NBSP ;         }
                    }
        p.Start();
$
      p.BeginErrorReadLine();
                     p.BeginOutputReadLine();
                     int timeout = 1000000;
;    如果((p.WaitForExit(超时))及及(outputWaitHandle.WaitOne(/ *超时* /))及;&安培; errorWaitHandle.WaitOne(/ *超时* /))
&NBSP ;                   {
                    &NBSP ;   //流程已完成检查process.ExitCode这里
                        如果(output.Length&0)
                &NBSP ;           OnCommandFinished(真,output.ToString());
               &NBSP ;       否则如果(error.Length&0)
                         {
                    &NBSP ;       OnCommandFinished(假的,error.ToString());
               &NBSP ;        }
                    &NBSP ;  否则
                    &NBSP ;   {
                    &NBSP ;       OnCommandFinished(假的,"未指定的错误");
               &NBSP ;        }
                    }
                   否则
                    {
                    &NBSP ;   //超时
                  &NBSP ;     OnCommandFinished(假的,"命令处理超时");
                     }
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");
}
....
不幸的是,我从来没有这个工作。此外,我甚至没有收到错误消息,因为DataErrorReceived事件中的Data部分始终为null。当然,如果我在控制台中执行xcopy命令,它就可以工作。我想这是因为在Arguments属性中有一些文本格式化/转义
。我实际上已经尝试将xcopy命令和选项集成到批处理文件中,从上面的代码中调用批处理文件,但所有情况都变得更糟:我不再收到任何消息了。我花了几天时间编写这个程序,但后来
我尝试使用Python进行子进程:
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 = [在AllTargetComputerNames中为x设置了[r'\\'+ x + r'\d $ \DestDir']
b $ b#print(SourceLanPath)
#print(DestLanPaths)
$
for DestLanPaths中的destLanPath:
subprocess.call(['xcopy',SourceLanPath,destLanPath,args])
#
DestLanPaths = [r'\\' + x + r'\d$\DestDir' for x in AllTargetComputerNames]
# print(SourceLanPath)
# print(DestLanPaths)
for destLanPath in DestLanPaths :
subprocess.call(['xcopy', SourceLanPath, destLanPath, args])
Python程序或多或少一次工作!我猜Python subprocess.call方法比C#版本更好地处理xcopy的不同参数。有什么想法为什么c#版本不起作用?我在C#代码中做错了吗?
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?
祝你好运
Johannes
推荐答案
我会首先考虑 ,因为它可以进行多线程复制(/ MT:x)。
I would look into ROBOCOPY first, cause it can do multi-threaded copying (/MT:x).
这篇关于Windows 7中Process类的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!