4

コードで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 の使用は、開発マシンと同じドメイン内にいる場合 (問題が発生しているこの 1 つ以上のすべての呼び出しに対して)、および単純な DOS コマンド (rmdir および mkdir) クロスドメインを実行している場合に正常に機能します。 (この呼び出しの直前に行っているため)。

ただし、次のコマンドを実行すると、次のようになります。

C:\7Zip\7za x "C:[ファイル パスにスペースを含む]\__STAGING__\App01 [トランク - 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;
        }
4

1 に答える 1

0

これは実際には答えではありませんが、非常によく似た問題に遭遇しています。同じドメインで実行していますが、説明と同じ結果が表示されます。

C# コードまたは PowerShell から PsExec を実行するたびに、プロセスがハングしているように見えます。リモート サーバーを監視すると、PSEXESVC プロセスが起動し、リモート サーバーで実行しようとしていたコマンドが表示されます。コマンドは正常に終了しますが、PSEXESVC がハングしているようです。

私が渡しているリモートコマンドは次のとおりです。cmd /c dir E:\temp

CreateNoWindow を false に設定し、リダイレクトを false に設定して、LINQPad からこれをテストしました。開いたコマンド プロンプトは、期待される出力を返します。出力を再度キャプチャしようとすると、すぐにプロセスがハング状態に戻ります。

これは、1 年か 2 年前に同じコードを使用して C# から機能していたことを知っているので、何が変更されてハングするようになったのかわかりません。

于 2012-12-20T23:18:54.050 に答える