英文:
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 ' ^
public class Foo { ^
public static string Bar() { return \"hi!\"; } ^
} ^
'; ^
[Foo]::Bar()
-
逃逸规则的概述在 此答案 中;这里有一些值得注意的事项:
-
Here-strings (
@"<newline>...<newline>"@and@'<newline>...<neline>'@) 不能使用,因为它们对空白字符有严格要求,特别是要求在@"/@'开头之后和@"/@'结尾之前都有 换行符,而cmd.exe使用^进行行连续时 不会 产生换行符。因此,你的方法不会起作用(即使删除了@"开头后多余的;)。 -
在可能的情况下,请使用
'...''(verbatim (single-quoted) strings),这样可以简化转义。
请注意,PowerShell 的 常规 字符串文字不仅仅是这里的字符串,也可以跨足多行,这正是上述解决方案利用的。 -
当你需要使用
"时,请转义为\"- 如果在给定的内部行上出现"单独 或者有 不对称数量 的",请将其 / 最后一个转义为\^"(如此)。- 请注意,
\"...\"外部的任何内容被视为cmd.exe中的 非引用,因此诸如&和|等元字符需要在此进行单独的^转义。
- 请注意,
-
-
你应该能够将这些规则应用到你的
FlashWindowExP/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 ' ^
public class Foo { ^
public static string Bar() { return \"hi!\"; } ^
} ^
'; ^
[Foo]::Bar()
-
An overview of the escaping rules is in this answer; a few things worth noting here:
-
Here-strings (
@"<newline>...<newline>"@and@'<newline>...<neline>'@) cannot be used, because they have strict whitespace requirements, notably requiring a newline both immediately after the opening@"/@'as well as before the closing@"/@', whereascmd.exe's line-continuation with^does not result in newlines. Therefore, your approach won't work (even with the extraneous;after the opening@"removed). -
Use
'...'(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
", escape them as\"- if a"occurs alone or there is an uneven number of them on a given interior line, escape it / the last one as\^"(sic).- Note that anything outside
\"...\"is seen as unquoted bycmd.exe, so that metacharacters such as&and|require individual^-escaping there.
- Note that anything outside
-
-
You should be able to apply these rules to your
FlashWindowExP/Invoke declaration.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论