如何在Windows中随时捕获命令提示符的显示输出?

如何在Windows中随时捕获命令提示符的显示输出?,第1张

概述如何在Windows中随时捕获命令提示符的显示输出

我打算在特定时刻捕获在命令提示符(cmd窗口)中显示的信息并将其发送到文本文件。

我在C / C ++中有一个应用程序,它是由像这样的批处理脚本启动的:

c:myProgramInC.exe echo "Ending with error" PAUSE

myProgramInC.exe总是运行(无限循环),所以如果我的脚本到达echo命令,这意味着我的应用程序以asynchronous结束。

我想要得到的是脚本的结束执行之前的前面的行,因为我的myProgramInC.exe总是打印有关正在发生的事情的信息,这将是非常有用的,看看发生错误时发生了什么。 像这样的东西

在Delphi中button上的自定义窗口提示

windows Git bash提示符不显示函数的颜色

自动有脚本input是在windows CMD是/否提示

Bash输出发生在提示符之后,而不是之前,这意味着我必须手动按回车

如何自动响应linux Bash脚本中的提示?

c:myProgramInC.exe **** Execution of process to get te prevIoUs N lines in the command prompt **** echo "Ending with error" PAUSE

我知道CMD窗口有一个缓冲区,我一直在想从这样的缓冲区捕获所有这些数据。 以任何方式将这些信息作为文本存储在文件中?

我一直在尝试一些更专业的事情,以便与ProcDump的内存转储,但由于我有各种myProgramInC.exe同时运行(每一个存储在不同的位置)我只是得到消息“多进程匹配指定的名称“。 而其余的选项对我来说没有用,因为我的应用程序没有响应,它只是结束。

有任何想法吗?

怪异的windows提示行为恢复与psql工具的转储

如何在服务启动时查看日志文件?

如何为工具栏上的button启用自动工具提示?

当启动提示符时重新启动资源pipe理器作为pipe理员在windows 8不起作用

改变〜/ .mc / ini不生效

您可以使用ReadConsoleOutputCharacter函数轻松地在C中执行此 *** 作。

快速的技巧是在for /f执行,你甚至不需要批处理文件,你可以直接从cmd行执行:


for /f "tokens=*" %F in ('c:myProgramInC.exe') do @echo %F >>myPrograminC.log

这将抑制所有的输出,直到你的程序异常结束,只有这样才能将所有的消息写入文件。 如果您的应用程序很少写入日志消息(或快速失败:-)),它应该可以正常工作。 我用10000行测试了它。

下面的批处理代码是基于相同的想法 – 请注意,即使它只写了5最后一行, 它仍然必须扫描通过所有这些,所以我不知道它比上述1班轮好。

@echo off setlocal for /f "tokens=*" %%P in ('c:myProgramInC.exe') do ( for /L %%C in (4,-1,1) do ( set /A next=%%C+1 call set line_%%next%%=%%line_%%C%% ) set line_1=%%P ) echo program ended abnormally! %date% %time% for /L %%C in (5,1) do call echo %%line_%%C%%

最后,这是我得到它的工作。 在Harry Johnston的建议下,我搜索了ReadConsoleOutputCharacter函数的工作方式,并且运行了下一个程序。

#include "stdafx.h" #include <iostream> #include <windows.h> #include <fstream> #define BUFFER_SIZE 50000 int main(){ HANDLE hOut; COORD location = {0,0}; char *buffer=NulL; DWORD numberRead; std::ofstream fileLog; buffer = new TCHAR[BUFFER_SIZE]; if ( buffer==NulL ) { printf("nError: memory Could not be allocated.n"); return 1; } fileLog.open ("logger.txt"); if ( fileLog.fail() ) { printf("nError: file Could not be opened.n"); return 1; } hOut = GetStdHandle(STD_OUTPUT_HANDLE); ReadConsoleOutputCharacter(hOut,buffer,BUFFER_SIZE,location,&numberRead); fileLog << buffer ; free(buffer); fileLog.close(); return 0; }

我在互联网上找到的大部分代码,现在我没有网址(除了来自另一个论坛网站,我不知道是否可以引用竞争对手的网站),但在谷歌一个搜索不难找到它。

我添加了写入文件和分配内存的部分。 它在VS C ++ 6中完美运行。

这对我来说很好,虽然可能会更好。 两件事情不是很好

它将缓冲区中的所有内容写入文件,但不保留换行符,因此我得到一个文本文件,其中包含所有信息。

无法定义要捕获多少行。 它只需要从缓冲区的开头到程序开始的地方,但这并不坏,但是由于这个应用程序应该运行在不同的服务器上,每个服务器对于每一组命令提示符窗口都有不同的缓冲区,效率并不高只是在某些情况下使用50000字节的缓冲区时,缓冲区较小。 我认为这可能很多,但是由于它是实时分配的,使用尽可能多的内存也许并不是错误的。

好吧,可能有一个更好的方法来做到这一点,但这将工作假设你有PowerShell。

创建一个名为Get-ConsoleAsText.ps1的PowerShell脚本文件,其中包含以下脚本。 请注意 ,我没有创建这个脚本。 我在windows PowerShell博客 – 捕获控制台屏幕上找到它。

################################################################################################################# # Get-ConsoleAsText.ps1 # # The script captures console screen buffer up to the current cursor position and returns it in plain text format. # # Returns: ASCII-encoded string. # # Example: # # $textfilename = "$env:tempConsoleBuffer.txt" # .Get-ConsoleAsText | out-file $textfilename -enCoding ascii # $null = [System.Diagnostics.Process]::Start("$textfilename") # # Check the host name and exit if the host is not the windows PowerShell console host. if ($host.name -ne 'ConsoleHost') { write-host -Foregroundcolor Red "This script runs only in the console host. You cannot run this script in $($host.name)." exit -1 } # Initialize string builder. $textBuilder = new-object system.text.stringbuilder # Grab the console screen buffer contents using the Host console API. $bufferWIDth = $host.ui.rawui.BufferSize.WIDth $bufferHeight = $host.ui.rawui.Cursorposition.Y $rec = new-object System.Management.automation.Host.Rectangle 0,($bufferWIDth),$bufferHeight $buffer = $host.ui.rawui.GetBufferContents($rec) # Iterate through the lines in the console buffer. for($i = 0; $i -lt $bufferHeight; $i++) { for($j = 0; $j -lt $bufferWIDth; $j++) { $cell = $buffer[$i,$j] $null = $textBuilder.Append($cell.Character) } $null = $textBuilder.Append("`r`n") } return $textBuilder.ToString()

如果您自己调用PowerShell脚本,它将读取控制台缓冲区并将其写回到屏幕

PowerShell -noprofile -sta -command "C:ScriptsGet-ConsoleAsText.ps1"

您也可以像这样调用它来将内容捕获到文件中:

PowerShell -noprofile -sta -command "C:ScriptsGet-ConsoleAsText.ps1 | Out-file MyOutput.txt -enCoding ascii"

如果要处理它并在批处理文件中执行一些 *** 作,可以调用它并使用FOR命令处理输出。 我将把这个练习留给你。

所以,例如,你的批处理文件看起来像这样捕获控制台输出到一个文件:

c:myProgramInC.exe echo "Ending with error" PowerShell -noprofile -sta -command "C:ScriptsGet-ConsoleAsText.ps1 | Out-file MyOutput.txt -enCoding ascii" PAUSE

有一件事立刻就要将命令行的输出重定向到一个文件:

c:myProgramInC.exe >> myProgramInC.log

那么你可以看到什么是日志文件。

如果任何错误消息将被报告回命令输出流,则可以通过重定向 *** 作符(STDOUT)(标准输出)和STDERR(标准错误)轻松地重定向它。 取决于你是否要捕捉输出和/或错误,取决于你。 更可能的是,你正在寻找像这样的东西:

命令2 >>文件名

“2”是重定向 *** 作符的一部分,表示STDERR将被重定向并附加到文件名。

来源,例子和文件:

http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx

http://ss64.com/nt/Syntax-redirection.HTML

总结

以上是内存溢出为你收集整理的如何在Windows中随时捕获命令提示符的显示输出?全部内容,希望文章能够帮你解决如何在Windows中随时捕获命令提示符的显示输出?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1211745.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存