我搜索并阅读了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应用程序并执行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不能与stdout一起工作如何从psexec命令中捕获输出以将其写入文件???
请参阅以下链接了解psexec的问题,关于这个url的最后一个回复提到了一种将进程输出写入文件而不使用stdout的方法,我是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 ...
我希望避免使用stdout并以某种方式找到一种方法来获取此命令的输出,或者除非有其他东西我在看?另外,不要为任何人做更多的工作,但如果你从sysinternals d / l psexec.exe并使用远程主机上的命令测试它,你会看到。我在这个上花了2天时间:(试图弄清楚如何使用psexec或者找一些其他快速方法在主机上执行远程命令并获得ouptput。
更新:
我放弃了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文件但是0字节没有信息。
所以,如果我使用psexec命令在windows cmd行中运行批处理文件,它的工作原理非常好!! ???
然后验证psexec是我将批处理文件更改为:
的问题ipconfig /all >c:\test.txt
我执行上面的代码并且工作正常在test.txt文件中创建输出.. ??? !!!!
为什么不使用psexec我错过了什么?如果它是psexec,有没有人 关于如何在远程Windows主机上执行命令并获取我的任何建议 输出???
答案 0 :(得分:2)
我对这个问题的答案对我有用。
希望其他人会发现它很有用。
我真的花了最后两个小时用这个撕掉我的头发。 psexec工具使用正常的命令提示符运行完全正常,但是当尝试重定向流时,它会截断输出并且只返回一半输出。
最后我如何解决我的问题是一个小问题。我将命令的输出传送到文本文件并将其读回以从函数返回它。
我还必须将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);
答案 1 :(得分:2)
我有完全相同的问题。当我使用psexec运行时,我得到了“Windows ip config。”作为第一行。我尝试使用paexec它运作良好。我使用了Marius的代码。
注意:如果你不使用参数中的第一个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();
答案 2 :(得分:1)
您确定源代码是否正确?这个链接有点老了......也许它固定了!
下面举例说明如何重定向标准输出并通过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();
答案 3 :(得分:1)
我找到了解决方案。显然psexec不会用c sharp工作。所以我想出了一些wmi代码连接到一个远程主机,它的工作完美! :)
我使用microsoft的WMICodeCreator.exe为远程主机上的进程方法创建C#的wmi代码,哇,这个工具很棒,因为wmi代码对我来说有点混乱。
答案 4 :(得分:0)
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();