在 CMD 批处理文件中使用 FlashWindowEx

huangapple go评论71阅读模式
英文:

Using FlashWindowEx in a CMD batch file

问题

我有一个CMD批处理文件,需要很长时间才能处理,我希望通过闪烁CMD窗口来警示用户需要一些输入。这个示例在PowerShell中很有效,但如果我尝试从CMD中编译它,就会在第一行失败。类似的问题在这里讨论,但似乎从未提供解决方案。所以,有人有想法如何使这个工作并让我的CMD窗口闪烁吗?编辑:@mklement0的答案让我朝正确的方向前进。谢谢。

英文:

I have a CMD batch file which takes a long time to process and I wish to alert the user that some input is required by flashing the CMD window.

This example works great in powershell but if I try to compile it from within CMD by

powershell -c "Add-Type -TypeDefinition @\";"^
 "using System;"^
..... and so on

it fails at the very first line.
Similar problem discussed here but looks like there was never a solution given.

So, does anyone have ideas as to how I can make this work and get my CMD window to flash?

edit: @mklement0's answer got me in the right direction. THANK YOU.

答案1

得分: 3

<!-- language-all: sh -->

cmd.exe 传递多行 PowerShell 命令并不简单,需要大量小心的转义。

这里有一个最简示例,使用 Add-Type:使用 C# 代码,它定义了一个名为 [Foo] 的类,具有静态的 Bar() 方法,然后从 PowerShell 调用它:

powershell -noprofile -c Add-Type -TypeDefinition &#39; ^
  public class Foo { ^
    public static string Bar() { return \&quot;hi!\&quot;; } ^
  } ^
  &#39;; ^
  [Foo]::Bar()
  • 逃逸规则的概述在 此答案 中;这里有一些值得注意的事项:

    • Here-strings (@&quot;&lt;newline&gt;...&lt;newline&gt;&quot;@ and @&#39;&lt;newline&gt;...&lt;neline&gt;&#39;@) 不能使用,因为它们对空白字符有严格要求,特别是要求在 @&quot; / @&#39; 开头之后和 @&quot; / @&#39; 结尾之前都有 换行符,而 cmd.exe 使用 ^ 进行行连续时 不会 产生换行符。因此,你的方法不会起作用(即使删除了 @&quot; 开头后多余的 ;)。

    • 在可能的情况下,请使用 &#39;...&#39;' (verbatim (single-quoted) strings),这样可以简化转义。
      请注意,PowerShell 的 常规 字符串文字不仅仅是这里的字符串,也可以跨足多行,这正是上述解决方案利用的。

    • 当你需要使用 &quot; 时,请转义为 \&quot; - 如果在给定的内部行上出现 &quot; 单独 或者有 不对称数量&quot;,请将其 / 最后一个转义为 \^&quot;(如此)。

      • 请注意,\&quot;...\&quot; 外部的任何内容被视为 cmd.exe 中的 非引用,因此诸如 &amp;| 等元字符需要在此进行单独的 ^ 转义。
  • 你应该能够将这些规则应用到你的 FlashWindowEx P/Invoke 声明中。

英文:

<!-- language-all: sh -->

Passing multiline PowerShell commands from cmd.exe is nontrivial and requires lots of careful escaping.

Here's a minimal example with Add-Type: Using C# code, it defines class [Foo] with a static Bar() method and then calls it from PowerShell:

powershell -noprofile -c Add-Type -TypeDefinition &#39; ^
  public class Foo { ^
    public static string Bar() { return \&quot;hi!\&quot;; } ^
  } ^
  &#39;; ^
  [Foo]::Bar()
  • An overview of the escaping rules is in this answer; a few things worth noting here:

    • Here-strings (@&quot;&lt;newline&gt;...&lt;newline&gt;&quot;@ and @&#39;&lt;newline&gt;...&lt;neline&gt;&#39;@) cannot be used, because they have strict whitespace requirements, notably requiring a newline both immediately after the opening @&quot; / @&#39; as well as before the closing @&quot; / @&#39;, whereas cmd.exe's line-continuation with ^ does not result in newlines. Therefore, your approach won't work (even with the extraneous ; after the opening @&quot; removed).

    • Use &#39;...&#39; (verbatim (single-quoted) strings), where possible, which simplifies escaping.
      Note that PowerShell's regular string literals, not just here-strings, are also capable of spanning multiple lines, which the solution above takes advantage of.

    • When you do need to use &quot;, escape them as \&quot; - if a &quot; occurs alone or there is an uneven number of them on a given interior line, escape it / the last one as \^&quot; (sic).

      • Note that anything outside \&quot;...\&quot; is seen as unquoted by cmd.exe, so that metacharacters such as &amp; and | require individual ^-escaping there.
  • You should be able to apply these rules to your FlashWindowEx P/Invoke declaration.

huangapple
  • 本文由 发表于 2023年6月2日 02:56:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76384913.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定