コードで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;
}