如何在 C# 中捕获 Shell 命令输出?
摘要:
- 在远程计算机上查询注册表
- 捕获应用程序中使用的输出
- 需要在 csharp 中
- 到目前为止使用的所有方法都只能在本地计算机上查询
- 任何希望不胜感激
完整问题:
我需要找到一种在中运行命令行命令的方法csharp 并捕获其输出。我知道如何在 Perl 中执行此操作,下面是我将在 Perl 中使用的代码。
#machine to check
my $pc = $_[0];
#create location of registry query
my $machine = "\\\\".$pc."\\HKEY_USERS";
#run registry query
my @regQuery= `REG QUERY $machine`;
欢迎任何有关如何在 csharp 中执行此操作的建议。到目前为止,我尝试使用RegistryKey OurKey =Registry.Users方法,效果很好,但我无法查询远程计算机上的注册表。
如果您需要更多信息,请告诉我。
解决方案:(感谢@Robaticus)
private void reg(string host)
{
string build = "QUERY \\\\" + host + "\\HKEY_USERS";
string parms = @build;
string output = "";
string error = string.Empty;
ProcessStartInfo psi = new ProcessStartInfo("reg.exe", parms);
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
System.Diagnostics.Process reg;
reg = System.Diagnostics.Process.Start(psi);
using (System.IO.StreamReader myOutput = reg.StandardOutput)
{
output = myOutput.ReadToEnd();
}
using (System.IO.StreamReader myError = reg.StandardError)
{
error = myError.ReadToEnd();
}
Output.AppendText(output + "\n");
}
Summary:
- query registry on remote machine
- capture output to use in application
- needs to be in csharp
- so far all methods used can only query on the local machine
- any hope is greatly appreciated
Full issue:
I need to find a way to run a commandline command in csharp and capture its output. I know how to do this in Perl, below is the code I would use in Perl.
#machine to check
my $pc = $_[0];
#create location of registry query
my $machine = "\\\\".$pc."\\HKEY_USERS";
#run registry query
my @regQuery= `REG QUERY $machine`;
Any suggestions on how to do this in csharp would be welcome. So far ive tried using the RegistryKey OurKey = Registry.Users method and it works great but i can not query the registry on a remote machine.
Please let me know if you need any more information.
SOLUTION:(Thank you to @Robaticus)
private void reg(string host)
{
string build = "QUERY \\\\" + host + "\\HKEY_USERS";
string parms = @build;
string output = "";
string error = string.Empty;
ProcessStartInfo psi = new ProcessStartInfo("reg.exe", parms);
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
System.Diagnostics.Process reg;
reg = System.Diagnostics.Process.Start(psi);
using (System.IO.StreamReader myOutput = reg.StandardOutput)
{
output = myOutput.ReadToEnd();
}
using (System.IO.StreamReader myError = reg.StandardError)
{
error = myError.ReadToEnd();
}
Output.AppendText(output + "\n");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可能需要对此进行一些调整,但这里有一些(对原始代码稍作修改)重定向进程的 stdout 和 stderr 的代码:
You might have to tweak this a bit, but here's some (slightly modified from the original) code that redirects stdout and stderr for a process:
实际上,您可以在命令行中运行的任何内容都可以在具有类似约束的 C# 程序中运行。有几种方法可以做到这一点,一种是通过异步进程命令,如我在我的 博客 中所示。您只需以主动方式写入和读取命令行即可。从这里开始,只需弄清楚您想要完成什么以及如何使用命令行来完成它即可。然后将其插入程序
如您所见,您只需实例化该类,处理输出事件,然后开始编写命令,就像在命令提示符中键入一样。
它的工作原理如下:
Practically anything you can run in the command line you can run in a C# program with similar constraints. There's a few ways to do it, one is via Asynchronous process commands as I show in my blog. You just write and read to the command line in an active fashion. From here, just figure out what you want to accomplish and how to do it with a command line. Then plug it into the program
As you can see, you simply instantiate the class, handle the output event, and start writing commands just like you were typeing into the command prompt.
Here’s how it works:
这是我使用的一个类。它改编自我不久前在博客文章中找到的代码,但进行了各种其他修改。
Here's a class I use. It's adapted from code I found in a blog posting a while ago, but with various other modifications.
这并没有回答问题,而是
Registry.OpenRemoteBaseKey
方法以与REG
命令相同的方式连接到另一台计算机的注册表。调用RegistryKey.GetSubKeyNames
获取与REG QUERY
相同的输出。This doesn't answer the question, but the
Registry.OpenRemoteBaseKey
method connects to another machine's registry in the same way that theREG
command does. CallRegistryKey.GetSubKeyNames
to obtain the same output asREG QUERY
.您可以使用 System.Diagnostics.Process 类捕获 StandardOutput 和 StandardError。
http://msdn.microsoft.com/en-us/library /system.diagnostics.process.aspx
请务必阅读文档的备注部分。必须正确设置进程类的某些属性才能使 StandardOutput 可用(例如,UseShellExecute 必须设置为 false)。
You can capture StandardOutput and StandardError using the System.Diagnostics.Process class.
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx
Be sure to read the remarks section of the documentation. Certain properties of the process class have to be set correctly for StandardOutput to be available (e.g. UseShellExecute must be set to false).
正如我在这条评论中提到的这个答案,我改编了该答案中的代码并创建了一个库:
来自库自述文件:
所有库代码都在此文件中:
基本上,(唯一的)库类使用 .NET 流来写入命令进程的输入流并读取其输出和错误流。使用单独的线程(即并行)读取输出和错误流,以避免 “向其标准错误流写入足够内容以填满默认缓冲区大小的程序会出现死锁”。
As I mentioned in this comment on this answer, I adapted the code in that answer and created a library:
From the library README:
All of the library code is in this file:
Basically, the (sole) library class uses .NET streams to both write to the command process's input stream and read both its output and error streams. The output and error streams are read using separate threads (i.e. in parallel) to avoid "a deadlock for a program that writes enough to its standard error stream to fill up the default buffer size".