I know this is a problem in how I'm passing the arguments but I can't figure it out as it looks like I've successfully escaped the characters that might cause a problem.
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>
I'm at a loss!
CodePudding user response:
In testing it appears that it is treating $Runcmd
— both executable path and parameters — as one complete executable path to execute. I believe this is explained by the following section of 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.
Instead, pass the executable path and parameters to the call operator separately...
$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
You'll notice that $MyArgs
is now an array and not a [String]
. It seems that if $MyArgs
is a [String]
or a single-element array it gets passed to the executable as one parameter surrounded by double quotes. Stored as above each array element gets passed as a parameter with no additional quoting. If you still want to define $MyArgs
using one line of text you could do so like this...
$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 ' '
All of the above is why, for anything but ad hoc commands, I would prefer the self-documenting, obvious-as-to-which-string-is-treated-as-which nature of a Start-Process
call with explicitly-named parameters over the call operator. Given...
$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"'
...then both this...
Start-Process -FilePath $RunPath -ArgumentList $MyArgsText
...and this...
# NOTE: This only works because the path parameters contain no spaces
$MyArgs = $MyArgsText -split ' '
Start-Process -FilePath $RunPath -ArgumentList $MyArgs
...execute $RunPath
with the same parameters.
CodePudding user response:
I think every time I tried to include both the EXE name and the parameters in the same string, 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 in $Runcmd to view the actual parameters the EXE will be receiving.
This code example uses the Stop-parsing token (--%) and environmental variables to build the parameters passed to the EXE in $Runcmd.
$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%