PsExec 1.98(源自C#进程)在跨域运行7Zip时永远不会完成

PsExec 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

我使用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
};
当我在与开发机器相同的域中时(对于我正在进行的所有调用,而不仅仅是我遇到的问题),以及在跨域执行简单的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命令,它可以正常工作。我没有尝试在本地运行它。我现在正在尝试。我还从我的开发命令提示符运行了完整的命令,它起了作用。