将Windows命令提示符内容获取到文本文件 [英] Getting a Windows command prompt contents to a text file
问题描述
我想编写一个批处理实用程序,以将命令提示符窗口的输出复制到文件中.我以最大9999行的深度运行命令提示符窗口,有时我想获取其输出在屏幕外的命令的输出.我可以使用 Ctrl-A
, Ctrl-C
键手动执行此操作,然后将结果粘贴到记事本中-我只想通过调用将其自动处理到批处理文件中到:
I want to write a batch utility to copy the output of a command prompt window to a file. I run my command prompt windows with the maximum depth of 9999 lines, and occasionally I want to grab the output of a command whose output is off-screen. I can do this manually with the keys Ctrl-A
, Ctrl-C
and then pasting the result into Notepad - I just want to automate it in a batch file with a call to:
SaveScreen <text file name>
我知道我可以使用重定向来做到这一点,但这将涉及到知道我需要预先保存批处理命令序列的输出.
I know I can do it with redirection, but that would involve knowing that I will need to save the output of a batch command sequence beforehand.
所以,如果我有一个批处理脚本:
So if I had a batch script:
call BuildPhase1.bat
if "%ErrorLevel% gtr 0 goto :ErrorExit
call BuildPhase2.bat
if "%ErrorLevel% gtr 0 goto :ErrorExit
call BuildPhase3.bat
if "%ErrorLevel% gtr 0 goto :ErrorExit
我可以写:
cls
call BuildPhase1.bat
if "%ErrorLevel% gtr 0 call SaveScreen.bat BuildPhase1.err & goto :ErrorExit
call BuildPhase2.bat
if "%ErrorLevel% gtr 0 call SaveScreen.bat BuildPhase2.err & goto :ErrorExit
call BuildPhase3.bat
if "%ErrorLevel% gtr 0 call SaveScreen.bat BuildPhase3.err & goto :ErrorExit
或者当我看到运行失败时,我可以只键入 SaveScreen batch.log
.
or I could just type SaveScreen batch.log
when I see that a run has failed.
我的实验使我走了这么远:
My experiments have got me this far:
<!-- : Begin batch script
@cscript //nologo "%~f0?.wsf" //job:JS
@exit /b
----- Begin wsf script --->
<package>
<job id="JS">
<script language="JScript">
var oShell = WScript.CreateObject("WScript.Shell");
oShell.SendKeys ("hi folks{Enter}") ;
oShell.SendKeys ("^A") ; // Ctrl-A (select all)
oShell.SendKeys ("^C") ; // Ctrl-C (copy)
oShell.SendKeys ("% ES") ; // Alt-space, E, S (select all via menu)
oShell.SendKeys ("% EY") ; // Alt-space, E, Y (copy via menu)
// ... invoke a notepad session, paste the clipboard into it, save to a file
WScript.Quit () ;
</script>
</job>
</package>
我的击键使它进入了命令提示符,因此大概我把焦点对准了正确的窗口-似乎只是忽略了 Ctrl
和 Alt
修饰符.它还可以识别 Ctrl-C
,但不能识别 Ctrl-A
.因为它已忽略 Ctrl-A
来选择所有文本,所以Ctrl-C会使批处理文件认为它已经看到了break命令.
My keystrokes are making it to the command prompt so presumably I have the correct window focused - it just seems to be ignoring the Ctrl
and Alt
modifiers. It also recognises Ctrl-C
but not Ctrl-A
. Because it has ignored the Ctrl-A
to select all the text, the Ctrl-C causes the batch file to think it has seen a break command.
我看到了其他答案,例如这一个,但是他们都使用重定向来处理方法,而不是在按需"事实之后进行处理.
I've seen the other answers like this one but they all deal with methods using redirection, rather than a way of doing it after the fact "on demand".
*更新*
基于@dxiv的指针,这是该例程的批处理包装器:
On the basis of @dxiv's pointer, here is a batch wrapper for the routine:
Get-ConsoleAsText.bat
Get-ConsoleAsText.bat
:: save the contents of the screen console buffer to a disk file.
@set "_Filename=%~1"
@if "%_Filename%" equ "" @set "_Filename=Console.txt"
@powershell Get-ConsoleAsText.ps1 >"%_Filename%"
@exit /b 0
Powershell例程与链接中介绍的差不多,除了:
The Powershell routine is pretty much as was presented in the link, except that:
-
我必须对其进行清理以删除选择/复制/粘贴操作中引入的一些更有趣的字符替换.
I had to sanitise it to remove some of the more interesting character substitutions the select/copy/paste operation introduced.
原件也保存了尾随空格.那些现在被修剪.
The original saved the trailing spaces as well. Those are now trimmed.
Get-ConsoleAsText.ps1
Get-ConsoleAsText.ps1
# Get-ConsoleAsText.ps1 (based on: https://devblogs.microsoft.com/powershell/capture-console-screen/)
#
# 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:temp\ConsoleBuffer.txt"
# .\Get-ConsoleAsText | out-file $textFileName -encoding ascii
# $null = [System.Diagnostics.Process]::Start("$textFileName")
#
if ($host.Name -ne 'ConsoleHost') # Check the host name and exit if the host is not the Windows PowerShell console host.
{
write-host -ForegroundColor Red "This script runs only in the console host. You cannot run this script in $($host.Name)."
exit -1
}
$textBuilder = new-object system.text.stringbuilder # Initialize string builder.
$bufferWidth = $host.ui.rawui.BufferSize.Width # Grab the console screen buffer contents using the Host console API.
$bufferHeight = $host.ui.rawui.CursorPosition.Y
$rec = new-object System.Management.Automation.Host.Rectangle 0,0,($bufferWidth - 1),$bufferHeight
$buffer = $host.ui.rawui.GetBufferContents($rec)
for($i = 0; $i -lt $bufferHeight; $i++) # Iterate through the lines in the console buffer.
{
$Line = ""
for($j = 0; $j -lt $bufferWidth; $j++)
{
$cell = $buffer[$i,$j]
$line = $line + $cell.Character
}
$line = $line.trimend(" ") # remove trailing spaces.
$null = $textBuilder.Append($line)
$null = $textBuilder.Append("`r`n")
}
return $textBuilder.ToString()
推荐答案
The contents of the console buffer can be retrieved with the PS script from PowerShell's team blog Capture console screen mentioned in a comment, now edited into OP's question.
还可以更改最后一行,以将内容复制到剪贴板,而不是将其返回.
The last line could also be changed to copy the contents to the clipboard instead of returning it.
Set-Clipboard -Value $textBuilder.ToString()
作为旁注,在 StringBuilder如何工作中讨论了使用 StringBuilder
而不是直接串联的原因.在内部使用C#和如何实现StringBuilder类.
As a side note, the reasons for using a StringBuilder
rather than direct concatenation are discussed in How does StringBuilder work internally in C# and How the StringBuilder class is implemented.
这篇关于将Windows命令提示符内容获取到文本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!