如何将 STDOUT 输出保存到文本文件?
我有一个程序,它利用第三方命令行工具来生成日志。第 3 方将其所有输出生成到 STDOUT,然后用户必须使用 " > test.txt"
命令保存文件。
然而,该程序以某种方式生成一定数量的报告,但不是整个报告。这是使用命令
C:\Test\ftk\ripxp>ripxp.exe -r C:\test\ftk\ntuser.dat -d "C:\System Volume\_rest ore{BB12863B-2C77-46C9-BCDA-1810E52F1089}" -p runmru > C:\test\test05.txt
在命令行控制台上可以工作,在程序上只能部分工作。
错误已缩小归因于参数错误或文件保存错误部分(streamReader)。因此,该错误可能是由于 STDOUT 未正确保存所致,
因此有人可以提供有关代码的建议吗?谢谢
! H. Carvey):
RipXP v.20081001 - CLI RegRipper tool
RipXP [-r Reg hive file] [-p plugin module][-d RP dir][-lgh]
Parse Windows Registry files, using either a single module from the plugins folder.
Then parse all corresponding hive files from the XP Restore Points (extracted from
image) using the same plugin.
-r Reg hive file...Registry hive file to parse
-g ................Guess the hive file (experimental)
-d RP directory....Path to the Restore Point directory
-p plugin module...use only this module
-l ................list all plugins
-h.................Help (print this information)
Ex: C:\>rip -g
C:\>rip -r d:\cases\ntuser.dat -d d:\cases\svi -p userassist
All output goes to STDOUT; use redirection (ie, > or >>) to output to a file.
copyright 2008 H. Carvey
守则:
static void Main(string[] args)
{
// Automatically finds folder that starts with _restore
DirectoryInfo directoryInfo = new DirectoryInfo(@"C:\System Volume\");
DirectoryInfo restoreFolder = directoryInfo.GetDirectories().FirstOrDefault(d => d.Name.StartsWith("_restore"));
// Gets the folder name
String baka = restoreFolder.Name;
if (restoreFolder == null)
throw new DirectoryNotFoundException();
Process process = new Process();
process.StartInfo.FileName = @"C:\test\ftk\ripxp\ripxp.exe";
process.StartInfo.Arguments = @"-r C:\test\ftk\ntuser.dat -d C:\System Volume\" + restoreFolder.Name + " -p runmru";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
String text = @"-r C:\test\ftk\ntuser.dat -d C:\System Volume\" +restoreFolder.Name + " -p runmru";
Console.WriteLine(baka);
Console.WriteLine(text);
// Strangely the program only outputs the first section "-r C:\test\ftk\ntuser.dat" argument results.....
System.IO.StreamReader reader = process.StandardOutput;
String sRes = reader.ReadToEnd();
StreamWriter SW;
SW = File.CreateText(@"C:\test\test01.txt");
SW.WriteLine(sRes);
SW.Close();
Console.WriteLine("File Created Successfully");
reader.Close();
}
I have a program which utilizes a 3rd party command line tool to generate logs. The 3rd party generates all its output to the STDOUT which the user must then use the " > test.txt"
command to save the file.
However the program somehow generates a certain amount of report generated but not the entire report. This was test by using the command
C:\Test\ftk\ripxp>ripxp.exe -r C:\test\ftk\ntuser.dat -d "C:\System Volume\_rest
ore{BB12863B-2C77-46C9-BCDA-1810E52F1089}" -p runmru > C:\test\test05.txt
on the command line console which works and on the program which works only partially.
The errors were narrowed down to either the arguments error or the file saving error part (streamReader). Therefore the error could be due to the STDOUT not being properly saved.
Therefore may someone please advise on the codes? Thanks!
The Arguments for the 3rd party tool(2008 H. Carvey):
RipXP v.20081001 - CLI RegRipper tool
RipXP [-r Reg hive file] [-p plugin module][-d RP dir][-lgh]
Parse Windows Registry files, using either a single module from the plugins folder.
Then parse all corresponding hive files from the XP Restore Points (extracted from
image) using the same plugin.
-r Reg hive file...Registry hive file to parse
-g ................Guess the hive file (experimental)
-d RP directory....Path to the Restore Point directory
-p plugin module...use only this module
-l ................list all plugins
-h.................Help (print this information)
Ex: C:\>rip -g
C:\>rip -r d:\cases\ntuser.dat -d d:\cases\svi -p userassist
All output goes to STDOUT; use redirection (ie, > or >>) to output to a file.
copyright 2008 H. Carvey
The Codes:
static void Main(string[] args)
{
// Automatically finds folder that starts with _restore
DirectoryInfo directoryInfo = new DirectoryInfo(@"C:\System Volume\");
DirectoryInfo restoreFolder = directoryInfo.GetDirectories().FirstOrDefault(d => d.Name.StartsWith("_restore"));
// Gets the folder name
String baka = restoreFolder.Name;
if (restoreFolder == null)
throw new DirectoryNotFoundException();
Process process = new Process();
process.StartInfo.FileName = @"C:\test\ftk\ripxp\ripxp.exe";
process.StartInfo.Arguments = @"-r C:\test\ftk\ntuser.dat -d C:\System Volume\" + restoreFolder.Name + " -p runmru";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
String text = @"-r C:\test\ftk\ntuser.dat -d C:\System Volume\" +restoreFolder.Name + " -p runmru";
Console.WriteLine(baka);
Console.WriteLine(text);
// Strangely the program only outputs the first section "-r C:\test\ftk\ntuser.dat" argument results.....
System.IO.StreamReader reader = process.StandardOutput;
String sRes = reader.ReadToEnd();
StreamWriter SW;
SW = File.CreateText(@"C:\test\test01.txt");
SW.WriteLine(sRes);
SW.Close();
Console.WriteLine("File Created Successfully");
reader.Close();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您是否正在等待子进程完成?看来您太早开始阅读其输出了。可以这样完成:
此外,您可以在完成之前开始通过委托接收输出。像这样(每行文本都调用委托):
Are you waiting for the child process to finish? It looks like you start reading its output too early. It could be done like this:
Also, you can start receiving the output via delegates before it finishes. Like this (the delegate is called for each line of text):
您可以让 .NET 在进程退出时通知您,然后读取输出。因为,正如 detunized 在他的回答+评论中提到的那样,如果您在 Reader.ReadToEnd() 完成之前调用它,您将无法获得所有输出。如果你想一想,那就很明显了——数据还没有产生,你怎么能指望读者阅读它呢?
通过使用事件,您将不会阻止启动线程的方法,如果您有 GUI 应用程序并且不想在子进程运行时冻结用户界面,这将非常有用。
该过程完成后将调用此方法:
You can have .NET inform you when the process has exited and then read the output. Because, as detunized mentioned in his answer+comment, if you call
reader.ReadToEnd()
before it has completed, you won't get all the output. If you think of it, it's quite obvious - the data hasn't been produced yet, so how can you expect the reader to read it?By using events you will not block the method that starts the thread which can be quite useful if you have a GUI application and don't want to freeze the user interface while the child process is running.
This method will be called when the process has completed:
System.Console 类有一个
SetOut
方法应该可以满足您的需要。您应该在程序执行开始时调用Console.SetOut(yourTextWriter)。
只需将其添加到程序的第一行:
The System.Console class has a
SetOut
method that should do what you need.You should call
Console.SetOut(yourTextWriter)
at the beginning of your program's execution.Just add this at the first line of the program:
您需要使用 OutputDataReceived 事件。此 MSDN 文章解释了如何完成此操作:
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived(v=vs .110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
在处理程序内部使用 StreamWriter 将输出写入文件,如下所示:
You need to use the OutputDataReceived event. This MSDN article explains how this is done:
https://msdn.microsoft.com/en-us/library/system.diagnostics.process.outputdatareceived(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
Inside of the handler write the output to a file using the StreamWriter like: