PsExec 1.98(源自C#进程)在跨域运行7Zip时永远不会完成
我使用C#.NET 4进程和代码启动PsExecPsExec 1.98(源自C#进程)在跨域运行7Zip时永远不会完成,c#,c#-4.0,7zip,psexec,C#,C# 4.0,7zip,Psexec,我使用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, RedirectStandardOutp
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
};
当我在与开发机器相同的域中时(对于我正在进行的所有调用,而不仅仅是我遇到的问题),以及在跨域执行简单的DOS命令(rmdir和mkdir)(正如我在调用之前所做的那样),使用PsExec可以很好地工作
但是,当我让它运行以下命令时:
C:\7Zip\7za x“C:[文件路径包括空格]\\\\\\\\\\\\\\\\\\\\\\\ App01[Trunk-STAGE\\ U 20121217.2].7z“-o”C:[文件路径包括空格]\\\\\\\\\\\\\\\\\\\\\\\\\\'-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;
}
试试看
{
使用(var进程=新进程())
{
var startInfo=新进程startInfo(psExecLocation)
{
Arguments=string.Format(@“\\{0}-accepteula-u{1}-p{2}{3}”,服务器名,用户名,密码,命令),
RedirectStandardError=true,
重定向标准输出=真,
CreateNoWindow=true,
StandardErrorEncoding=Encoding.UTF8,
StandardOutputEncoding=Encoding.UTF8,
UseShellExecute=false
};
process.StartInfo=StartInfo;
var processOutput=“”;
动作动作=(对象、事件参数)=>
{
if(string.IsNullOrWhiteSpace(eventArgs.Data)==false)
processOutput+=string.Format(“{0}\r\n”,eventArgs.Data);
};
process.OutputDataReceived+=新的DataReceivedEventHandler(操作);
process.ErrorDataReceived+=新的DataReceivedEventHandler(操作);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
//PsExec中似乎有一个错误,即使是输出,也会使所有内容都出错。这就解决了这个问题
输出=”;
if(string.IsNullOrWhiteSpace(processOutput)==false)
{
输出=进程输出;
//错误代码0表示它已工作/成功。任何其他“错误代码”表示出现故障
var lowerOutput=processOutput.ToLower().Replace(“\r\n”和“).Trim();
返回LowerOutput.EndsWith(“错误代码0”)| | LowerOutput.EndsWith(“错误代码0”);
}
//如果它到达这里,psexec不会返回任何东西。这永远不会发生(强调应该)
返回false;
}
}
捕获(例外情况除外)
{
Logging.Logger.LogError(ex);
输出=”;
返回false;
}
这不是一个真正的答案,但我遇到了一个非常类似的问题。我在同一个域中运行,但看到的结果与描述的相同
每次我从C#代码或PowerShell运行PsExec时,进程都会挂起。当我观察远程服务器时,我看到PSEXESVC进程启动,同时还有我试图在远程服务器上运行的命令。命令正常退出,但PSEXESVC似乎挂起
我传递的远程命令是:cmd/cdire:\temp
我已经在LINQPad中测试了这一点,CreateNoWindow设置为false,redirects设置为false,打开的命令提示符确实返回了预期的输出。一旦我再次尝试捕获输出,进程就会回到挂起状态
我知道这在一年或两年前C#使用相同的代码时起作用,所以我不确定是什么改变导致它现在挂起。请显示用于读取流程输出(重定向)的代码。原始问题已更新。当您以完全相同的方式从cmd提示符启动psexec时,是否会出现相同的问题?(据我所知,你确实做得很好——我过去也做过类似的事情)。我可以从命令提示符(在服务器上)运行7Z命令,它可以正常工作。我没有尝试在本地运行它。我现在正在尝试。我还从我的开发命令提示符运行了完整的命令,它起了作用。