英文:
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
中的 非引用,因此诸如&
和|
等元字符需要在此进行单独的^
转义。
- 请注意,
-
-
你应该能够将这些规则应用到你的
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 ' ^
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
FlashWindowEx
P/Invoke declaration.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论