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