从 Powershell 执行 NirSoft SearchMyFiles.exe 时出现问题

Problem Executing NirSoft SearchMyFiles.exe from Powershell

我知道我传递参数的方式存在问题,但我无法弄清楚,因为看起来我已经成功转义了可能导致问题的字符。

PS> $ExecutionPath = "G:\BEKDocs\NonInstPrograms\NirSoftx64"
$PgmName       = "Searchmyfiles.exe"
$RunCmd        = Join-Path -Path "$ExecutionPath" -ChildPath "$PgmName"
$MyArgs        = " `/config `"G:\BEKDocs\TestSMF.cfg`" `/StartSearch `/ExplorerCopy `/stext `"G:\BEKDocs\TestSMF.txt`""
$runcmd        += $MyArgs
& $Runcmd

---Results: No file Created no Error messages displayed---

--- Show the Created Command ---

PS> $RunCmd
G:\BEKDocs\NonInstPrograms\NirSoftx64\Searchmyfiles.exe /config "G:\BEKDocs\TestSMF.cfg" /StartSearch /ExplorerCopy /stex
t "G:\BEKDocs\TestSMF.txt"

--- Try to Execute the command from History ---

PS> G:\BEKDocs\NonInstPrograms\NirSoftx64\Searchmyfiles.exe /config "G:\BEKDocs\TestSMF.cfg" /StartSearch /ExplorerCopy /stex
t "G:\BEKDocs\TestSMF.txt"

--- Result: No file created no Error messages displayed. ---

--- Type the command by hand ---

PS> G:\BEKDocs\NonInstPrograms\NirSoftx64\searchmyfiles.exe /config "G:\BEKDocs\TestSMF.cfg" /StartSearch /ExplorerCopy /stext "G:\BEKDocs\TestSMF.txt"

--- Result: File CREATED as expected ---
PS> 

我很茫然!

我想每次我尝试在同一个字符串中包含 EXE 名称和参数时,The call operator (&) fails. With that in mind, try something where $Runcmd is pointing only to the EXE and nothing else. This also makes testing easy by temporarily placing the path to EchoArgs 在 $Runcmd 中查看 EXE 将接收的实际参数。

此代码示例使用 Stop-parsing token (--%) 和环境变量构建传递给 $Runcmd 中的 EXE 的参数。

$ExecutionPath = "G:\BEKDocs\NonInstPrograms\NirSoftx64"
$PgmName       = "Searchmyfiles.exe"
$RunCmd        = Join-Path -Path "$ExecutionPath" -ChildPath "$PgmName"
$Env:Config = '"G:\BEKDocs\TestSMF.cfg"'
$Env:SText = '"G:\BEKDocs\TestSMF.txt"'
& $Runcmd --% /config %Config% /StartSearch /ExplorerCopy /stext %SText%

在测试中,它似乎将 $Runcmd——可执行路径和参数——作为一个完整的可执行路径来执行。我相信 about_Operators...

的以下部分对此进行了解释

The call operator does not parse strings. This means that you cannot use command parameters within a string when you use the call operator.

PS> $c = "Get-Service -Name Spooler"
PS> $c
Get-Service -Name Spooler
PS> & $c
& : The term 'Get-Service -Name Spooler' 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.

相反,将可执行路径和参数分别传递给调用运算符...

$ExecutionPath = "G:\BEKDocs\NonInstPrograms\NirSoftx64"
$PgmName       = "Searchmyfiles.exe"
$RunPath       = Join-Path -Path "$ExecutionPath" -ChildPath "$PgmName"
$MyArgs        = @(
    '/config',       '"G:\BEKDocs\TestSMF.cfg"',
    '/StartSearch',
    '/ExplorerCopy',
    '/stext',        '"G:\BEKDocs\TestSMF.txt"'
)

& $RunPath $MyArgs

您会注意到 $MyArgs 现在是一个数组,而不是 [String]。似乎如果 $MyArgs[String] 或 single-element 数组,它会作为 一个参数 被双引号括起来传递给可执行文件。如上存储,每个数组元素都作为参数传递,没有额外的引用。如果您仍想使用一行文本定义 $MyArgs,您可以这样做...

$MyArgsText    = '/config "G:\BEKDocs\TestSMF.cfg" /StartSearch /ExplorerCopy /stext "G:\BEKDocs\TestSMF.txt"'
# NOTE: This only works because the path parameters contain no spaces
$MyArgs        = $MyArgsText -split ' '

以上所有就是为什么除了临时命令之外,我更喜欢 self-documenting、obvious-as-to-which-string-is-treated-as-which 使用 explicitly-named 参数调用的 Start-Process 性质通过呼叫运营商。鉴于...

$ExecutionPath = "G:\BEKDocs\NonInstPrograms\NirSoftx64"
$PgmName       = "Searchmyfiles.exe"
$RunPath       = Join-Path -Path "$ExecutionPath" -ChildPath "$PgmName"
$MyArgsText    = '/config "G:\BEKDocs\TestSMF.cfg" /StartSearch /ExplorerCopy /stext "G:\BEKDocs\TestSMF.txt"'

...然后这两个...

Start-Process -FilePath $RunPath -ArgumentList $MyArgsText

...还有这个...

# NOTE: This only works because the path parameters contain no spaces
$MyArgs        = $MyArgsText -split ' '

Start-Process -FilePath $RunPath -ArgumentList $MyArgs

...使用相同的参数执行$RunPath