我使用CreateProcess
(win32)创建了一个powershell
进程,并从其中读取原始字节。
但是我发现它产生了大量不可见字符,例如\u{1b}[2J\u{1b}[m\u{1b}[
有没有办法停止这种情况发生?
*确实可以手动去除这些字符,但我希望还有其他方法。
我使用CreateProcess
(win32)创建了一个powershell
进程,并从其中读取原始字节。
但是我发现它产生了大量不可见字符,例如\u{1b}[2J\u{1b}[m\u{1b}[
有没有办法停止这种情况发生?
*确实可以手动去除这些字符,但我希望还有其他方法。
你提到了powershell
(powershell.exe
),即Windows PowerShell的CLI。
Windows PowerShell(与PowerShell(Core)7+不同,见下文)本身不使用基于VT / ANSI转义序列的着色/格式化。
这意味着在你的情况下第三方代码正在生成VT序列,因此您必须停用(或重新配置)它以避免输出中出现这些序列。
一个主要候选人是自定义的prompt
函数;这些函数通常涉及着色以获得更好的命令行体验。
然而,在对powershell.exe
进行编程式使用时,只有当您将PowerShell命令传递给CLI的stdin时,才会看到提示函数打印的内容,同时还需要通过向CLI传递参数-File -
(指示它从stdin读取命令)或默认方式。
要完全排除提示函数的输出,请使用-Command -
,如您之前问题的答案中所讨论的。
如果您确实想要它,但希望使用默认提示字符串,请使用-NoProfile
参数来禁止加载$PROFILE
,这通常在编程处理中更可取。
Select-String
}}的输出中以及在v7.2+中的格式化输出中,特别是表格输出的列标题/列表输出的属性名称。
在 PowerShell 7.2+ 中,你可以以下方式明确地抑制它们:
注意:通常不需要明确地禁用 VT (ANSI) 序列,因为当输出未发送到主机(显示)时,PowerShell自动抑制它们;也就是说,$PSStyle.OutputRendering
默认为 Host
[1]。
$PSStyle.OutputRendering
仅适用于由 PowerShell 的 for-display formatting system 格式化的对象,且仅在将此类格式化表示转换为字符串数据时才适用,无论是通过 Out-String
显式转换,还是通过 >
/ Out-File
隐式转换,或者当管道到一个外部程序时。[2]从 PowerShell 外部启动之前:
通过定义 NO_COLOR
环境变量,并设置为任意值,如 1
。
这会使 PowerShell 在启动时将 $PSStyle.OutputRendering
设为 PlainText
,指示 PowerShell 不使用 VT / ANSI 转义序列。
越来越多的外部程序也遵循该环境变量 - 请参考 no-color.org
或者,通过将 TERM
环境变量设置为 xtermm
/ xterm-mono
(也会将 $PSStyle.OutputRendering
设置为 'plaintext'
):
dumb
$host.UI.SupportsVirtualTerminal
反映出 $false
(正如文档中所述),但 $PSStyle.OutputRendering
仍保持其默认值 Host
,并且实际格式化输出(例如来自 Get-Item /
的输出)仍使用颜色。TERM
可能比 NO_COLOR
在让外部程序不发出 VT 序列方面更有效 - 但最终无法保证。TERM
,尤其是将其设置为值 dumb
,因为外部程序(在类 Unix 平台上)可能依赖于 TERM
变量来推断托管终端应用程序的(非与颜色相关的)功能和特性(将变量设置为 dumb
将完全消除这些推断,而值 xtermm
/ xterm-mono
请注意,使用VT序列的第三方PowerShell代码,特别是在PowerShell(Core)7+之前的版本中,可能不会遵守上述任何用于禁用它们的标准机制(尽管可能提供自定义机制)。
[1] 这适用于 v7.2.0-preview.9 及以后的版本,其中 Host
成为默认选项,而之前的默认选项 Automatic
已被完全移除。在 v7.3.0 的预览版本中,Ansi
暂时成为默认选项,但自官方 v7.3.0 版本发布后,(明智的)默认选项又变回了 Host
。
[2] 值得注意的是,在 v7.3+ 中,带有嵌入 ANSI / VT 转义序列的 字符串 数据不再受到 $PSStyle.OutputRendering
的影响(这是从 v7.2 版本起的更改),因为字符串不受格式化系统处理(它们按原样打印)。
TERM
设置为dumb
来禁用ANSI输出渲染。:SetEnvironmentVariable(TEXT("TERM"), TEXT("dumb"));
// proceed with your call to CreateProcess