Why don't .NET objects in PowerShell use the current directory?

Solution 1:

You can change .net working dir to powershell working dir:
[Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
After this line all .net methods like [io.path]::GetFullPath and [IO.File]::WriteAllText will work without problems

Solution 2:

The reasons PowerShell doesn't keep the .NET notion of current working directory in sync with PowerShell's notion of the working dir are:

  1. PowerShell working dirs can be in a provider that isn't even file system based e.g. HKLM:\Software
  2. A single PowerShell process can have multiple runspaces. Each runspace can be cd`d into a different file system location. However the .NET/process "working directory" is essentially a global for the process and wouldn't work for a scenario where there can be multiple working dirs (one per runspace).

Solution 3:

For convenience, I added the following to my prompt function, so that it runs whenever a command finishes:

# Make .NET's current directory follow PowerShell's
# current directory, if possible.
if ($PWD.Provider.Name -eq 'FileSystem') {
    [System.IO.Directory]::SetCurrentDirectory($PWD)
}

This is not necessarily a great idea, because it means that some scripts (that assume that the Win32 working directory tracks the PowerShell working directory) will work on my machine, but not necessarily on others.

Solution 4:

When you use filenames in .Net methods, the best practice is to use fully-qualified path names. Or use

$pwd\foo.cer

If you do in powershell console from:

C:\> [Environment]::CurrentDirectory

C:\WINDOWS\system32\WindowsPowerShell\v1.0

you can see what folder .net use.

Solution 5:

That's probably because PowerShell is running in System32. When you cd to a directory in PowerShell, it doesn't actually change the working directory of powershell.exe.

See:

PowerTip article on syncing the two directories

Channel9 forum thread