我正在使用带有代码的 C# .NET 4 进程启动 PsExec
var startInfo = new ProcessStartInfo(psExecLocation)
{
Arguments = string.Format(@"\\{0} -accepteula -u {1} -p {2} {3}", serverName, username, password, command),
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
StandardErrorEncoding = Encoding.UTF8,
StandardOutputEncoding = Encoding.UTF8,
UseShellExecute = false
};
当我与我的开发机器在同一个域中时,使用 PsExec 可以正常工作(对于我正在进行的所有调用,这不仅仅是我遇到的问题)以及在跨域执行简单的 DOS 命令(rmdir 和 mkdir)时(正如我在这次通话之前所做的那样)。
但是,当我让它运行以下命令时:
C:\7Zip\7za x "C:[文件路径包含空格]\__STAGING__\App01 [Trunk - STAGE_20121217.2].7z" -o"C:[文件路径包含空格]\__STAGING__\" -y -aoa
它永远不会回来。我可以看到它开始返回数据(我正在使用进程重定向输出并开始返回它所做的事情),但随后它突然停止并且什么也不做。调用后它永远不会返回
process.WaitForExit();
奇怪的是它确实成功完成了。我可以 RDP 进入我们正在提取文件的服务器,我可以在那里看到文件,只是 PsExec 没有返回任何内容。我已经尝试删除 -y -aoa 开关并移动事物的顺序,但似乎没有任何效果。仅供参考,我们试图在其中提取此内容的服务器是 Windows Server 2003 版本和 Windows Server 2008 R2 版本。
正如所问的,这正是我使用 PsExec 打开进程所要做的:
try
{
using (var process = new Process())
{
var startInfo = new ProcessStartInfo(psExecLocation)
{
Arguments = string.Format(@"\\{0} -accepteula -u {1} -p {2} {3}", serverName, username, password, command),
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
StandardErrorEncoding = Encoding.UTF8,
StandardOutputEncoding = Encoding.UTF8,
UseShellExecute = false
};
process.StartInfo = startInfo;
var processOutput = "";
Action<object, DataReceivedEventArgs> action = (obj, eventArgs) =>
{
if (string.IsNullOrWhiteSpace(eventArgs.Data) == false)
processOutput += string.Format("{0}\r\n", eventArgs.Data);
};
process.OutputDataReceived += new DataReceivedEventHandler(action);
process.ErrorDataReceived += new DataReceivedEventHandler(action);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
// There appears to be a fault in PsExec that has everything go to error even if it is output. This gets around that
output = "";
if (string.IsNullOrWhiteSpace(processOutput) == false)
{
output = processOutput;
// error code 0 means it worked / succeeded. Any other "error code" means something failed
var loweredOutput = processOutput.ToLower().Replace("\r\n", "").Trim();
return loweredOutput.EndsWith("error code 0.") || loweredOutput.EndsWith("error code 0");
}
// if it got here, psexec didn't return anything. That SHOULD never happen (emphasis on should)
return false;
}
}
catch (Exception ex)
{
Logging.Logger.LogError(ex);
output = "";
return false;
}