Почему объекты .NET в PowerShell не используют текущий каталог?

Когда вы используете объект .NET из PowerShell, и он принимает имя файла, он всегда кажется относительно C:\Windows\System32.

Например:

[IO.File]::WriteAllText('hello.txt', 'Hello World')

... будет писать C:\Windows\System32\hello.txt, а не C:\Current\Directory\hello.txt

Почему PowerShell делает это? Можно ли изменить это поведение? Если он не может быть изменен, как мне его обойти?

Я пробовал Resolve-Path, но это работает только с уже существующими файлами, и это слишком сложно делать все время.

Ответ 1

Причины, по которым PowerShell не поддерживает представление .NET текущего рабочего каталога в синхронизации с понятием PowerShell рабочего каталога:

  • Рабочие серверы PowerShell могут быть у поставщика, который даже не файловой системы например, HKLM:\Software
  • Один процесс PowerShell может иметь несколько пробелов. Каждая рабочая область может быть cd`d в другом файле расположение системы. Однако рабочий стол ".NET/процесс" по существу, глобальный для этого процесса и не сценарий, где может быть несколько рабочих каналов (по одному на каждое пространство).

Ответ 2

Вы можете изменить .net рабочий каталог в рабочую директорию powershell:
[Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
После этой строки все методы .net, такие как [io.path]::GetFullPath и [IO.File]::WriteAllText, будут работать без проблем

Ответ 3

Для удобства я добавил в свою функцию prompt следующее, чтобы она выполнялась при завершении команды:

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

Это не обязательно хорошая идея, поскольку это означает, что некоторые сценарии (предполагающие, что рабочий каталог Win32 отслеживает рабочий каталог PowerShell) будут работать на моем компьютере, но не обязательно на других.

Ответ 4

Когда вы используете имена файлов в методах .Net, рекомендуется использовать полные пути. Или используйте

$pwd\foo.cer

Если вы используете консоль PowerShell из:

C:\> [Environment]::CurrentDirectory

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

вы можете увидеть, какую папку .net использовать.

Ответ 6

Я столкнулся с той же проблемой давным-давно, и теперь добавлю следующее в начало моего профиля:

# Setup user environment when running session under alternate credentials and
# logged in as a normal user.
if ((Get-PSProvider FileSystem).Home -eq "")
{
    Set-Variable HOME $env:USERPROFILE -Force
    $env:HOMEDRIVE = Split-Path $HOME -Qualifier
    $env:HOMEPATH = Split-Path $HOME -NoQualifier
    (Get-PSProvider FileSystem).Home = $HOME
    Set-Location $HOME
}