来自sysinternals的stdout和psexec.exe问题
本文关键字:psexec exe 问题 stdout sysinternals 来自 | 更新日期: 2023-09-27 18:03:38
我已经搜索并阅读了关于sysinternals中psexec.exe不能与c#和stdout正常工作的问题。我现在正试图找出如何只是调用批处理文件,有以下而不是使用System.Diagnostics.Process调用psexec:
test.bat包含以下行:
psexec.exe ''hostname -u user -p password ipconfig /all >c:'test.txt
test.txt将保存在我运行c sharp应用程序并执行psexec的主机上。
当我执行以下命令时:
System.Diagnostics.Process psexec_run = new System.Diagnostics.Process();
psexec_run.StartInfo.FileName = "cmd.exe";
psexec_run.StartInfo.Arguments = @"/c """ + cur_dir + @"'test'test.bat""";
psexec_run.StartInfo.UseShellExecute = false;
psexec_run.Start();
psexec_run.WaitForExit();
我看到CMD窗口弹出,它运行一些东西,但不确定是什么,然后消失。
如果我执行以下命令:
System.Diagnostics.Process psexec_run = new System.Diagnostics.Process();
psexec_run.StartInfo.FileName = cur_dir + "''test''psexec.exe";
psexec_run.StartInfo.Arguments = @"''hostname -u user -p password ipconfig /all";
psexec_run.StartInfo.UseShellExecute = false;
psexec_run.Start();
psexec_run.WaitForExit();
然后我看到命令窗口打开,它运行psexec,这需要相当多的秒,我很快看到我需要的输出,但我没有办法捕获输出或将其写入文件。
我想我现在的问题是,因为psexec不会与标准输出工作,我怎么能捕获psexec命令的输出,将其写入文件??
看到下面的链接与psexec的问题,这个url上的最后一个回复提到了一种方法来写过程输出到一个文件,而不使用标准输出,我是c#的新手,我不知道如何写过程输出不使用标准输出:(
http://forum.sysinternals.com/psexec-fails-to-capture-stdout-when-launched-in-c_topic19333.html根据下面的回复,我尝试了以下操作:
ProcessStartInfo psi = new ProcessStartInfo(cur_dir + "''test''psexec.exe", @"''hostname -u user -p password ipconfig /all");
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
StreamReader myStreamReader = p.StandardOutput;
// Read the standard output of the spawned process.
string sOutput = myStreamReader.ReadToEnd();
我做了ReadToEnd,所以我要确保它得到了所有的输出,它没有!!由于某种原因,它只执行ipconfig输出的第一行。此外,由于某些原因,它打开的cmd窗口从未关闭。即使CreateNoWindow=true,代码也会挂起。所以我认为psexec和stdout又有问题了??因为我可以在本地主机上使用ipconfig/all命令运行这段代码,而不是使用psexec…
再次,我希望避免标准输出,并以某种方式找到一种方法来获得这个命令的输出,或者除非有其他东西我看?同样,不要为任何人做更多的工作,但是如果您从sysinternals中输入/l psexec.exe,并在远程主机上使用命令测试它,您将看到。我花了2天时间在这个上面:(试图弄清楚如何使用psexec或找到一些其他快速方法在主机上执行远程命令并获得输出。
更新:我放弃了c#代码中的psexec,我看到很多关于psexec吃输出,有一个子窗口进程等的帖子直到我的头疼:)所以我试图运行一个批处理文件和输出到一个文件,这是没有意义的…
我有一个批处理文件test.bat,下面是
psexec.exe '''hostname -u name -p password ipconfig /all >c:'test.txt
,当我运行下面的代码:
ProcessStartInfo psi = new ProcessStartInfo(cur_dir + @"'test'test.bat");
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
p.WaitForExit();
CMD窗口来了又走得很快,创建了test.txt文件,但是里面没有任何信息。
所以如果我用psexec命令在Windows CMD行中运行批处理文件,它工作得很好!
因此,为了验证psexec是问题,我将批处理文件更改为:ipconfig /all >c:'test.txt
我执行上面的代码,它工作良好,在test.txt文件中创建输出…??!!!!
为什么不与psexec工作,我错过了什么?如果是psexec,有没有人关于如何在远程Windows主机上执行命令并获得输出? ?
对于这个问题,我有一个对我有效的答案。
希望其他人会发现它有用。
我真的花了两个小时在这上面,把我的头发都扯掉了。psexec工具使用正常的命令提示符运行完全正常,但当试图重定向流时,它会截断输出,您只能得到一半的输出。
最后,我如何解决我的问题是一个小hack。我将命令的输出通过管道传输到一个文本文件,并将其读入以从函数返回。
我还必须将UseShellExecute设置为true。没有这个,它仍然无法工作。这有一个不幸的副作用,即显示控制台窗口。为了解决这个问题,我将窗口样式设置为隐藏,嘿,它很快就工作了!!
下面是我的代码:
string ExecutePSExec(string command)
{
string result = "";
try
{
string location = AppDomain.CurrentDomain.BaseDirectory;
// append output to file at the end of this string:
string cmdWithFileOutput = string.Format("{0} >{1}temp.log 2>&1", command,location );
// The flag /c tells "cmd" to execute what follows and exit
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + cmdWithFileOutput);
procStartInfo.UseShellExecute = true; // have to set shell execute to true to
procStartInfo.CreateNoWindow = true;
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden; // as a window will be created set the window style to be hiddem
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
// now read file back.
string filePath = string.Format("{0}temp.log", location);
result = System.IO.File.ReadAllText(filePath);
}
catch (Exception objException)
{
// Log the exception
}
return result;
}
及其用法:
string command = @"psexec.exe -l -u domain'username -p password /accepteula ''192.168.1.3 netstat -a -n";
ExecutePSExec(command);
我有完全相同的问题。我得到"Windows ip配置。"当我与psexec一起运行时,作为第一行。我尝试了paexec,它工作得很好。我用了马吕斯的密码。
注意:如果你不使用第一个cmd/c参数命令只运行在本地计算机上,即使你定义的目标为''remoteserver
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe");
psi.Arguments = @"cmd/c C:'paexec.exe '''192.168.2.5 -s -u test.local'administrator -p Password1 cmd /c ipconfig";
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
System.IO.StreamReader myStreamReader1 = p.StandardOutput;
p.WaitForExit();
string sOutput = myStreamReader1.ReadToEnd();
您确定您的源代码是正确的吗?那个链接有点老了…也许它是固定的!
下面是一个如何重定向标准输出并通过streamreader将整个输出放在字符串中的示例:
ProcessStartInfo psi = new ProcessStartInfo("tftp.exe");
// preferences for tftp process
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
StreamReader myStreamReader = p.StandardOutput;
p.WaitForExit();
// Read the standard output of the spawned process.
string sOutput = myStreamReader.ReadToEnd();
我找到了一个解决方案。显然,psexec在升c音中不起作用。所以我想出了一些wmi代码连接到远程主机,它的工作完美!!:)
我使用微软的WMICodeCreator.exe为远程主机上的进程方法创建c#的wmi代码,这个工具太神奇了,因为wmi代码对我来说有点混乱。
psexec的输出是StandardError而不是StandardOutput。我不知道为什么会这样。下面的代码片段访问它。
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.RedirectStandardError = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
errors = process.StandardError.ReadToEnd();
process.Close();