在脚本中定义数组时出错,但是如果输入它就可以工作

error defining array in a script, it works if typed out however

我正在尝试创建音频切换。我以前写过,但新的 OS 和 dll 更新迫使我重写它,我以前使用的方法似乎不再有效。 所以一开始我的第一行就吐出了这个错误:

$audio : The term '$audio' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that 
the path is correct and try again.
At D:\audiochanger.ps1:1 char:1
+ $audio = Get-AudioDevice -playback
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: ($audio:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

但如果我输入 $audio = Get-AudioDevice -playback 然后调用 $audio,它就可以正常工作。怎么回事?

$audio = Get-AudioDevice -playback
$audio.Name
if ($audio.Name -eq 'Speakers (Realtek High Definition Audio)') {
set-audiodevice 1 
}  Else {
set-audiodevice 2
}

Get-AudioDevice -playback

的输出

Index   : 2
Default : True
Type    : Playback
Name    : Speakers (Realtek High Definition Audio)
ID      : {0.0.0.00000000}.{2aa2a27b-4ebc-4355-bdf7-093a8f97ba46}
Device  : CoreAudioApi.MMDevice

or

Index   : 1
Default : True
Type    : Playback
Name    : Speakers (Logitech G533 Gaming Headset)
ID      : {0.0.0.00000000}.{1f5d6b65-fe9b-4bda-9508-d1a204149395}
Device  : CoreAudioApi.MMDevice

这是 运行 windows 10 和 powershell 5。我以前的工作代码可以在这里找到:

唯一合理的解释是您的脚本文件中 $audio 之前有 不可见的控制字符

如果您的行确实以 $audio = ... 开头,它将按预期被解释为 赋值 ;相反, 看起来像 $audio 被解释为 命令 的名称,这意味着 $ 不是实际上是第一个字符。

您可以按如下方式重现问题:

[char] 0x200b + '$audio = Get-AudioDevice -playback' > t.ps1
./t.ps1

由于 $audio 之前的控制字符 U+200B(ZERO WIDTH SPACE)) 不可见,上面会产生您看到的错误。

虽然这个特定的控制字符只是一个示例,但您可以按如下方式检查脚本第一行中的实际字符:

 & { 
   [int[]] [char[]] $Args[0] | % { '0x{0:x} [{1}]' -f $_, [char] $_ } 
 } (get-content D:\audiochanger.ps1)[0]

解决办法是去掉不可见的字符;以下 可能 有效,具体取决于您的案例中实际存在的字符:

 (Get-Content D:\audiochanger.ps1) -replace '\p{Cf}' > D:\audiochanger.CleanedUp.ps1

正则表达式 \p{Cf} 匹配所有不可见控制字符的实例 .