17

This must be something obvious, but I can't get this to work.

I'm trying to build a variable that should contain the path to an existing file, using an environment variable ($env:programfiles(x86)). However I keep getting errors, and I fail to see why.

This works fine (if the file exists):

PS C:\> $f = "C:\Program Files (x86)" + '\sometextfile.txt'
PS C:\> $f
C:\Program Files (x86)\sometextfile.txt
PS C:\> gci $f
    Directory: C:\Program Files (x86)
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        13/12/2010     14:03          0 sometextfile.txt
PS C:\>

However, this does not:

PS C:\> "$env:programfiles(x86)"
C:\Program Files(x86)
PS C:\> $f = "$env:ProgramFiles(x86)" + '\sometextfile.txt'
PS C:\> $f
C:\Program Files(x86)\sometextfile.txt
PS C:\> gci $f
Get-ChildItem : Cannot find path 'C:\Program Files(x86)\sometextfile.txt' because it does not exist.
At line:1 char:4
+ gci <<<<  $f
    + CategoryInfo          : ObjectNotFound: (C:\Program Files(x86)\sometextfile.txt:String) [Get-ChildItem], ItemNot
   FoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

What's happening, and how do I fix it?

4
  • 1
    Is the missing space in the second example just a typo? "Program Files (x86)" vs "Program Files(x86)" Commented Dec 13, 2010 at 13:52
  • it's not, I get it without space too. very strange Commented Dec 13, 2010 at 14:01
  • 2
    no, on a 64bit system you get two env variables: ${env:programfiles} and ${env:programfiles(x86)} Commented Dec 13, 2010 at 15:53
  • Maybe useful: geekswithblogs.net/Lance/archive/2009/12/29/… Commented Apr 3, 2013 at 10:37

2 Answers 2

26

Here is what is going on...

In any Windows PowerShell path empty characters or spaces need to be surrounded with a set of quotes or brackets. The PowerShell environment variable for the C:\Program Files (x86) is ${env:ProgramFiles(x86)}, not $env:ProgamFiles(x86) since PowerShell needs to escape the empty spaces in the real path.

If you use the '${env:ProgramFiles(x86)}' explicit environment variable, it works perfectly.


This won't work...

PS C:\> cd "$env:programfiles(x86)"
Set-Location : Cannot find path 'C:\Program Files(x86)' because it does not e
At line:1 char:3
+ cd <<<<  "$env:programfiles(x86)"
+ CategoryInfo          : ObjectNotFound: (C:\(x86):String)
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.

or this...

PS C:\> $env:ProgramFiles(x86)
Unexpected token '(' in expression or statement.
At line:1 char:19
+ $env:ProgramFiles( <<<< x86)
+ CategoryInfo          : ParserError: ((:String) [], Parent
+ FullyQualifiedErrorId : UnexpectedToken

But this works great...

PS C:\> ${env:ProgramFiles(x86)}
C:\Program Files (x86)
PS C:\> $f = "${env:ProgramFiles(x86)}" + "\sometextfile.txt"
PS C:\> $f
C:\Program Files (x86)\sometextfile.txt
PS C:\> gci $f
Directory: C:\Program Files (x86)


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        12/13/2010   8:58 AM          0 sometextfile.txt
Sign up to request clarification or add additional context in comments.

3 Comments

Per the previous poster, this is not a bug. In Powershell syntax, parentheses indicate a parameter that gets passed to a cmdlet or script. Since the environment variable stores a path has a set of parenthesis in it, the variable needs to be escaped and evaluated in-between the ${}. To see what I mean, try making a variable with parentheses in it, for example $dogs(areawesome) or $programs(x64) and you will get a 'Unexpected token '(' in expression or statement. The Powershell coders could have avoided this issue by making the environment variable "$env:ProgramFilesx86".
Your answer is correct but the reason isn't. A space in the resultant path has nothing to do with why this particular envvar requires {}. If it did, then $env:ProgramFiles would also require {} but it doesn't. The reason ProgramFiles(x86) misbehaves is purely a parser issue. As the parser evaluates $env:ProgramFiles(x86), it sees a new 'Group' expression when it sees the opening parens which is not valid given the current context. You can see this with the PowerShell tokenizer e.g.: [management.automation.psparser]::Tokenize('$env:ProgramFiles(x86)', [ref]$errors).
The PowerShell developers didn't name that environment variable. :P
2

That is weird and looks like a bug. Actually it is resolving the $env:programfiles variable and appending the rest of the string - which in this case just happens to be (x86).

This will work though:

$f =  ${env:ProgramFiles(x86)} + '\sometextfile.txt'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.