程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_607_0@如何解决如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?? 开发过程中遇到如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?的问题如何解决?下面主要结合日常开发的经验,给出你关于如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?的解决方法建议,希望对你解决如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?有所启发或帮助;

我在 CMD 脚本文件中使用以下代码

PowerSHell add-type -Assemblyname System.windows.Forms;^
$line_1 = 'Hello!';^
$line_2 = 'How are you?';^
[System.windows.Forms.messageBox]::Show($line_1)

以上只会显示($line_1)
如果使用 ($line_1`n$line_2),则不会显示任何内容。

如何让它同时显示$line_1$line_2

@H_607_0@解决方法

最简单的解决方案是(注意 \"$Line_1`n$Line_2\" 部分):

PowerSHell -c Add-Type -AssemblyName System.Windows.Forms; ^
$Line_1 = 'Hello!'; ^
$Line_2 = 'How are you?'; ^
[System.Windows.Forms.messageBox]::Show(\"$Line_1`n$Line_2\")

请注意,我已明确添加了 -c (-Command) 参数名称以表示正在传递 PowerSHell 命令字符串。然这在 Windows PowerSHell 中不是必需的,默认为 -Command,但在 PowerSHell (CorE) 7+ 中,-File 是现在是默认设置 - 请参阅 Windows PowerSHell 和 PowerSHell (CorE) 7+ 的 CLI 文档

也就是说,您必须$Line_1`n$Line_2 中使用 "...",一个 expandable String,并且您必须\-转义 { {1}} 个字符,以便 PowerSHell 不会将它们作为其命令行解析的一部分剥离(在没有整体双引号的情况下," 也可以使用) .


不幸的是,解析规则在使用 for /f改变,以便逐行处理 PowerSHell 的输出和/或将其捕获到变量中:

注意:下面使用 """ 来生成控制台输出,只是为了使用与 [Console]::WriteLine() 方法调用类似的语法,同时允许 {{1} 捕获某些内容}}。在现实生活中,没有很好的理由调用 [System.Windows.Forms.messageBox]::Show()

for /f
  • [Console]::WriteLine() 必须另外被转义(在 for /f "delims=" %%l in (' PowerSHell -c Add-Type -AssemblyName System.Windows.Forms^; ^ $Line_1 ^= 'Hello!'^; ^ $Line_2 ^= 'How are you?'^; ^ [Console]::WriteLine^(\"$Line_1`n$Line_2\"^) ') do echo [%%l] 所看到的 =,; ( ) 字符串之外)。

  • 如果您另外在 cmd.exe 中包含一个 "..." 字符串以防止空格规范化(请参阅下一节)该字符串则需要 \"...\"-转义嵌入的 "..." 元字符,您必须莫名其妙地在 initial ^ 前面加上 cmd.exe;例如,
    "

  • 换行符(位于命令内部行末尾的 ^)实际上在 ^"\"Marley ^& Me\"" 中是可选的,但为了一致性而将它们包含在内。 >


引用和转义要求摘要

  • 带有续行的多行技术(行尾的 ^) - 在语法上不能使用 for /f 引用整个 命令,因为 ^ 不支持双引号多行 Strings - 需要小心的 "..."-转义所有 cmd.exe 元字符,应该传递给PowerSHell,特别是^,此外,如果从cmd.exe 语句中调用PowerSHell& | < > ^ - 除非这些字符碰巧是 for /f 视为 double 引用的子字符串的一部分;例如,放置在 ,; = ( ) 字符串内的 cmd.exe - 例如& - 必须不能\"...\"-escaped(但见下文关于空白规范化)。

    • 作为一个例外,元字符 \"$Line_1`n & $Line_2\" 必须始终转义为 ^(仅适用于批处理文件,不适用于命令提示符 - 请参阅{{ 3}}).

    • 此外,如果 % 有效(或 %%setlocal enabledelayedexpansion 开头),cmd.exe 也必须转义,但如下所示:

      • 作为 /V:ON (siC) outside ! 所看到的 ^^! 字符串(其中另一个元字符只需要 一个 cmd.exe)
      • 作为 "..." inside 这样的字符串(其他元字符需要没有转义)。
    • 当通过 ^ 调用时,续行是可选 - 也就是说,您可以省略命令内部行末尾的 ^!

  • 每个语句都必须以 for /f 结尾(正如您所做的那样),因为换行符 (^) 导致输入之间没有 换行符行,因此 PowerSHell 将它们视为一行,多个语句必须以 ; 分隔。

  • 因为 ^ 和 PowerSHell 的 initial 命令行解析都不知道单引号字符串 (;) 并且因为 转义 cmd.exe 字符串中的 '...' 字符在命令行解析过程中没有 语法 功能,如果这些字符串包含空格,则会被分解为 多个 参数:

    • 实际上,这些字符串中多个相邻空格的运行被标准化为每个单个空格。例如,"\"...\" 最终被 PowerSHell 视为 'How are you?'\"How are you?\"

    • 为避免这种情况,另外将这些字符串括在未转义 'How are you?'中(如果 em>整个命令包含在 "How are you?") 中:
      ""..."

    • PowerSHell 最终应将其视为 "'How are you?'"(插值)字符串,但棘手的部分是 "\"How are you?\"" 无法识别 "..."-转义 cmd.exe 字符,因此 it\ 视为双引号字符串 ("),后跟一个不带引号的字符串 ("\"How are you?\""),后跟另一个双引号字符串 ("\")。因此,此类字符串中的任何 How are you?\ 元字符都必须再次进行 "" 转义才能传递到 PowerSHell(这适用于包装的 cmd.exe字符串,例如 ^);例如:'...'

      • PowerSHell (CorE) 7+ only 中,您可以通过使"'How are you?'" 而不是 "\"rock ^& roll"\" 来避免这种额外的 ^-escaping转义的 PowerSHell ""(在 Windows PowerSHell 上会再次导致空白规范化),与封闭的未转义 \" 结合有效地导致 三重双引号:"

PowerSHell 如何解析传递给其 CLI 的 "..." / """How are you?""" 参数的参数:

PowerSHell 为您提供传递命令字符串之间的选择

  • either:作为单个参数,包含在整体-Command中;例如:

    • -c
  • 或:多个 参数 - 可能单独使用 "..." 引用 - 然后 PowerSHell 将这些参数连接起来形成一个字符串;例如:

    • powersHell -c "Get-Date -Format 'yyyy MMM'"

在这两种情况下,未转义 "..." 个字符都从参数中剥离,因为为了命令行 而不是生成的 PowerSHell 命令。

剥离语法 powersHell -c Get-Date -Format "'yyyy MMM'" 字符并用空格连接结果参数后(如果适用),PowersHell 将结果字符串解释为 PowerSHell 代码

注意:这与您使用 " CLI 参数调用 脚本文件 并将参数传递给它时解析参数的方式有根本的不同 - 有关更多信息,请参阅 this answer .

,

显然 $Line_1 + "`n" + $Line_2"$Line_1`n$Line_2" 工作正常。将命令字符串从 cmd 发送到 PowerSHell 非常棘手,因为它具有传统的怪癖:

  • 在 cmd () 中,不同地方的特殊字符表示一个块
  • 令牌分隔符不仅是 <space><tab>,还有 ; , = <0x0B> <0x0C> and <0xFF>。这会更改 cmd 的标记化行为,但被调用的命令可能会再次使用其规则重新解析命令

根据文档,PowerSHell 期望最后一个参数中的单个字符串中的命令(这并不完全正确,因为文档没有正确更新),所以你需要引用整个内容或转义所有的分隔符。最简单的解决方案是使用单行并像这样转义 "`n" 中的引号

PowerSHell "Add-Type -AssemblyName System.Windows.Forms; $Line_1 = 'Hello!'; $Line_2 = 'How are you?'; [System.Windows.Forms.messageBox]::Show($Line_1 + \"`n\" + $Line_2)"

如果您想将命令放在多行中,则不能引用字符串。要将整个内容作为单个参数,现在您需要转义所有空格(在这种情况下您不需要转义 ;,可能是因为在将命令行传递给 PowerSHell 后,它会调用 {{ 1}} 并再次解析整个事情本身)

GetCommandLineW

或者,您可以通过直接使用 PowerSHell Add-Type^ -AssemblyName^ System.Windows.Forms;^ $Line_1^ =^ 'Hello!';^ $Line_2^ =^ 'How^ are^ you?';^ [Windows.Forms.messageBox]::Show($Line_1^ +^ \"`n\"^ +^ $Line_2)" 获取新行来避免使用 "`n" 字符串

[char]10

最后一个无需任何转义即可工作的解决方案,它利用 PowerSHell 的 PowerSHell -Command Add-Type -AssemblyName System.Windows.Forms;^ $Line_1 = 'Hello!';^ $Line_2 = 'How are you?';^ [System.Windows.Forms.messageBox]::Show($Line_1 + [char]10 + $Line_2) 选项接收 UTF-16 命令字符串的 base64 编码字符串。您可以通过在 PowerSHell 中运行它来获取编码版本

EncodedCommand

获得编码版本后,您可以从 cmd 调用它

$str = @'
>> Add-Type -AssemblyName System.Windows.Forms;
>> $Line_1 = 'Hello!';
>> $Line_2 = 'How are you?';
>> [System.Windows.Forms.messageBox]::Show($Line_1 + "`n" + $Line_2)
>> '@
PS C:\Users\phucl> [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($str))
QQBkAGQALQBUAHkAcABlACAALQBBAHMAcwBlAG0AYgBsAHkATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVwBpAG4AZABvAHcAcwAuAEYAbwByAG0AcwA7AAoAIAA9ACAAJwBIAGUAbABsAG8AIQAnADsACgAgAD0AIAAnAEgAbwB3ACAAYQByAGUAIAB5AG8AdQA/ACcAOwAKAFsAUwB5AHMAdABlAG0ALgBXAGkAbgBkAG8AdwBzAC4ARgBvAHIAbQBzAC4ATQBlAHMAcwBhAGcAZQBCAG8AeABdADoAOgBTAGgAbwB3ACgAIAArACAAIgAKACIAIAArACAAKQA=
,

有多种连接字符串的方法可以查找,但最简单的方法可能是使用 + 符号。 `n 是一个换行符,它将第 2 行置于第 1 行下方。请注意,` 是一个反引号(通常与波浪号 ~ 位于同一键上)

[System.Windows.Forms.messageBox]::Show($Line_1 + "`n" + $Line_2)

再次查看您的帖子后,我注意到您与 ($Line_1`n$Line_2) 很接近。你只是缺少一些双引号

[System.Windows.Forms.messageBox]::Show("$Line_1`n$Line_2")

PowersHell 很乐意将变量放在双引号内时替换它们的值。您可以阅读有关可扩展字符串 here 和 here

的更多信息

大佬总结

以上是大佬教程为你收集整理的如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?全部内容,希望文章能够帮你解决如何使 ($Line_1`n$Line_2) 在 CMD 脚本中工作?所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:如何使