我一直在尝试从运行psexec作为c# windows窗体应用程序的进程中获得控制台输出。我发现我可以在控制台应用程序中将标准输出(和标准错误)重定向到指定的文本文件,并且可以在使用的进程不是PsExec(例如ping)时重定向输出,但是当我尝试从windows窗体应用程序中使用PsExec时,我通常会在日志中获得空行,或者最多我能够获得第一行。我知道psexec有同步重定向输出的问题,但即使是异步也会遇到这个问题,但只有在Windows窗体应用程序中使用时。
运行进程的方法调用的代码:
class Tester
{
static readonly StringBuilder outputText = new StringBuilder();
static readonly StringBuilder errorText = new StringBuilder();
public void Installer(string command, string arguments)
{
using (var psexec = Process.Start(new ProcessStartInfo(
command,
arguments)
{
CreateNoWindow = true,
ErrorDialog = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
}))
{
psexec.OutputDataReceived += (sendingProcess, outLine) =>
outputText.AppendLine(outLine.Data);
psexec.ErrorDataReceived += (sendingProcess, errorLine) =>
errorText.AppendLine(errorLine.Data);
psexec.BeginOutputReadLine();
psexec.BeginErrorReadLine();
psexec.WaitForExit();
string text = outputText.ToString();
File.AppendAllText(@"C:testpsexec-test.log", text);
}
}
}
当在控制台应用程序中像这样调用时,上面的工作(为我提供我期望在指定文件中的psexec的输出):
class Program
{
static void Main(string[] args)
{
Tester test1 = new Tester();
test1.Installer("PsExec.exe", @"-h \remoteserver ipconfig");
}
}
但是,如果我从一个等效的Windows窗体应用程序中调用它,像这样:
public partial class Form1 : Form
{
Tester test = new Tester();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string sendAddress = Address.Text;
test.Installer("psexec.exe", @"-h \remoteserver ipconfig");
} }
我只得到:
Windows IP Configuration
完成了!没有ipconfig的其他结果。
在更大的应用程序中,我让其他一切都正常工作,我知道真正的工作已经完成(它在远程机器上运行安装程序,或多个远程机器),但我没有得到psexec的输出。是否有一些我错过了Windows窗体应用程序,以及如何获得重定向工作与psexec?
看起来你在开始这个过程时操之过急。让我惊讶的是,你得到了你想要的控制台应用程序。但我认为你想要创建你的进程,钩子事件,然后开始:
public void Installer( string command, string arguments, string logFile )
{
var outputText = new StringBuilder( );
var errorText = new StringBuilder( );
var startInfo = new ProcessStartInfo( command, arguments )
{
CreateNoWindow = true,
ErrorDialog = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
};
using ( var psexec = new Process( ) )
{
psexec.StartInfo = startInfo;
psexec.OutputDataReceived += ( _, dat ) => outputText.AppendLine( dat.Data );
psexec.ErrorDataReceived += ( _, dat ) => errorText.AppendLine( dat.Data );
psexec.Start( );
psexec.BeginOutputReadLine( );
psexec.BeginErrorReadLine( );
psexec.WaitForExit( );
File.AppendAllText( logFile, outputText.ToString( ) );
}
}