Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

running a program with spaces in Path with invoke-expression

4,352 views
Skip to first unread message

Frank

unread,
Apr 23, 2008, 11:51:01 PM4/23/08
to
Hi,

I have a situation where I need to define the executable with the path to be
used with invoke-expression. It works with putting the path in there but
because the path has a space, an error becomes of it. The program path has a
space in it where it is:

$testcmd = "C:\Program Files\test\testutil"

$CMD = "$testcmd param1"
invoke-expression $CMD

When I execute this, I get:

The term 'C:\Program' is not recognized as a cmdlet, function, operable
program, or script file. Verify the term and try again.

When I use & in place of invoke-expression, I also get an error. Is there a
way around this other than putting the directory of the executable in the
path?

Thanks in advance,


Spider Pig

unread,
Apr 24, 2008, 9:02:40 AM4/24/08
to
This is not a solution to your problem but might help towards a solution...

I did the following after reading your question:

$testcmd = "C:\Program Files\Movie Maker\moviemk.exe"

invoke-expression $testcmd - this gives an error
& $testcmd - this works

Well, to me this indicates that there is a difference between using "&" and
"invoke-expression"

Hmm, seems that "&" = "invoke-item" NOT "invoke-expression"

invoke-item $testcmd - works

Lets try with the parameter:

& $testcmd param1 - works too

BUT

invoke-item $testcomd param1 - no go

so "&" is not equal to "invoke-item" either.

As soon as you try and combine the app. path and the param it doesn't work
either , e.g.
$cmd = "$testcmd param1"
& $cmd

RickB

unread,
Apr 24, 2008, 10:02:55 AM4/24/08
to

There might be a better way but I know this works.

$cmd = "&'$testcmd' param1"
$executioncontext.InvokeCommand.invokescript($cmd)

As does this

$cmd = $executioncontext.InvokeCommand.NewScriptBlock("&'$testcmd'
param1")
$cmd.invoke()

Kiron

unread,
Apr 24, 2008, 11:41:58 AM4/24/08
to
Single-quote the executable's path and escape the space(s):
 
$testcmd = 'C:\Program` Files\test\testutil'
$CMD = "$testcmd param1"
invoke-expression $CMD

--
Kiron

Bob Landau

unread,
Apr 24, 2008, 11:48:00 AM4/24/08
to
Frank,

From what you've shown Invoke-Expression is an overkill. PS will do string
expansion for you nevertheless here are a few ways of doing it

## script "t 1.ps1"
param([string] $msg)

write-host $msg
## end of script "t 1.ps1"


> $t = '.\x y\t 1.ps1'

> & $t hello ## this in my opinion is the clearest and easiest

> invoke-expression '& $t hello'

> $s = 'powershell'

> invoke-expression '& $t $s'

Marc Magnin

unread,
Jul 29, 2009, 6:18:27 AM7/29/09
to

Hello,

I'm replying to this old post because it helped me to find a way to
dynamically call / run program requiring arguments like :

C:\Program files\Program\program.exe /verysilent /norestart
/LoadInf=".\conf.ini"

This work if I write directly the full command in powershell like :


Code:
--------------------

& C:\Program files\Program\program.exe /verysilent /norestart /LoadInf=".\conf.ini"

--------------------


Great!
But I have no idea of the command in advance... Heck!
So I tried several things like :


Code:
--------------------

& $fullCommandString
& $commandString $argsString
. $commandString $argsString
. $quotedCommandString $quotedArgsString
powershell -command "& {" $quotedCommandString $quotedArgsString "}"
invoke-item $commandString $argsString

--------------------

etc........

but I still had errors caused by space in "Program files" or slash of
arguments etc...

The way I found is to pass a string for the command and an array of
string for arguments :
(here I directly wrote the command in the code by in reality, $command
is feeded from and XML file)


Code:
--------------------

$command = "C:\Program files\Program\program.exe /verysilent /norestart /LoadInf='.\conf.ini'"
if($command -match "(?<appPath>.*\.[A-Za-z]+\s)(?<appArgs>.*)"){
$args = [regex]::Split($Matches.appArgs.trim(), "\s" )
& $Matches.appPath.trim() $args
}

--------------------


Hope thats helps.

Marc Magnin,
Pourquoi faire simple quand on peut faire compliqu� ?!


--
Marc Magnin

Marc Magnin

unread,
Jul 29, 2009, 7:22:00 AM7/29/09
to

I'have just found a better way by using the [diagnostics.process] class
cause i need to wait the end of execution :


Code:
--------------------



if($command -match "(?<appPath>.*\.[A-Za-z]+\s)(?<appArgs>.*)"){

$com =$Matches.appPath.trim()
$args = $Matches.appArgs.trim()
[diagnostics.process]::start($com, $args).WaitForExit()
}

--------------------

stej

unread,
Jul 29, 2009, 8:17:03 AM7/29/09
to
I replied only to author by mistake, so once again:
Start-process works ok for me. Just try:

Start-Process -FilePath "c:\Program Files\Internet Explorer
\iexplore.exe" -ArgumentList 'http://www.seznam.cz'

Marc Magnin

unread,
Jul 29, 2009, 9:35:57 AM7/29/09
to

Hi,

Start-Process is only available in PowerShell Community Extensions,
unfortunately, these extensions are not available in our office...

A good link about processes and powershell :
'Windows PowerShell Blog : Managing Processes in PowerShell'
(http://blogs.msdn.com/powershell/archive/2007/01/16/managing-processes-in-powershell.aspx)


-marc

tojo2000

unread,
Jul 29, 2009, 5:04:05 PM7/29/09
to
On Jul 29, 6:35 am, Marc Magnin <gu...@unknown-email.com> wrote:
> Hi,
>
> Start-Process is only available in PowerShell Community Extensions,
> unfortunately, these extensions are not available in our office...
>
> A good link about processes and powershell :
> 'Windows PowerShell Blog : Managing Processes in PowerShell'
> (http://blogs.msdn.com/powershell/archive/2007/01/16/managing-processe...)
>
> -marc
> Pourquoi faire simple quand on peut faire compliqué ?!
>
> --
> Marc Magnin

If you don't have Start-Process you could still try using

[System.Diagnostics.Process]::Start($your_command)

http://msdn.microsoft.com/en-us/library/system.diagnostics.process.start.aspx

OldDog

unread,
Jul 29, 2009, 10:47:56 PM7/29/09
to
> http://msdn.microsoft.com/en-us/library/system.diagnostics.process.st...

Not to be old fashioned, but I use the Short Path name in these cases.
You can find them by doing this:

C:\>dir *. /x
Volume in drive C is OS
Volume Serial Number is 66AB-C4DB

Directory of C:\

04/18/2007 04:37 PM <DIR> ATI
04/07/2007 12:53 PM <DIR> DELL
04/02/2007 01:36 PM <DIR> doctemp
04/02/2007 01:36 PM <DIR> Drivers
06/20/2009 11:54 AM <DIR> ISO
06/16/2007 11:46 PM <DIR> PHOTOS~1 Photoshop 7
06/21/2009 01:29 PM <DIR> PROGRA~1 Program Files
<-----
07/17/2009 09:01 AM <DIR> PSTools
07/12/2009 08:43 PM <DIR> Scripts
09/15/2007 07:07 PM <DIR> STARTM~1 Start Menu
06/28/2009 05:28 PM <DIR> Temp
04/07/2007 12:25 PM <DIR> Users
07/01/2009 05:41 PM <DIR> Windows

Then this: dir "Program Files" /x

Which shows you this:

07/29/2009 03:07 AM <DIR> INTERN~1 Internet Explorer
<----

So your command line looks like this:

"c:\Progra~1\INTERN~1\iexplore.exe"

Works for me.

OldDog

Larry__Weiss

unread,
Jul 29, 2009, 11:41:57 PM7/29/09
to
You have to be a little careful about expectations of the short names.
They aren't always the same on all systems. The "-1" "-2" etc, get assigned
first-created first-assigned, in my experience for names that are the same in
the first 6 characters.

- Larry

OldDog

unread,
Jul 30, 2009, 9:03:50 AM7/30/09
to

You can try this:

$a = New-Object -ComObject Scripting.FileSystemObject
$f = $a.GetFile("C:\Program Files\Internet Explorer\ExtExport.exe")
$f.ShortPath

Marc Magnin

unread,
Jul 31, 2009, 10:46:08 AM7/31/09
to

Hello !

Actually i work with this :


Code:
--------------------

$command = "C:\Program files\foo\foo.exe"
$arguments = "/verysilent /norestart /LoadInf='.\foo.ini'"
$startinfo = new-object System.Diagnostics.ProcessStartInfo
$startinfo.FileName = $command.fileName
$startinfo.Arguments = $command.arguments
[System.Diagnostics.Process]::Start($startinfo)

--------------------


This is quite perfect for me ;)

Best regards,

-marc

John Hart

unread,
Jun 10, 2022, 12:30:30 PM6/10/22
to
Soooo this little trick worked like a charm for me just now! I appreciate you putting it out there, good ole 'OLD SCHOOL'!
Thanks OldDog!
0 new messages