为什么PowerShell中的.NET对象不使用当前目录?

Rog*_*mbe 16 powershell

当您使用PowerShell中的.NET对象时,它需要一个文件名,它似乎总是相对于C:\Windows\System32.

例如:

[IO.File]::WriteAllText('hello.txt', 'Hello World')
Run Code Online (Sandbox Code Playgroud)

......会写C:\Windows\System32\hello.txt,而不是C:\Current\Directory\hello.txt

为什么PowerShell会这样做?这种行为可以改变吗?如果无法更改,我该如何解决?

我已经尝试了Resolve-Path,但这只适用于已经存在的文件,并且它总是太冗长而无法一直进行.

Den*_*rev 23

您可以更改.NET工作目录到PowerShell的工作目录:
[Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
这条线之后所有.NET方法,如[io.path]::GetFullPath[IO.File]::WriteAllText将没有任何问题的工作


Kei*_*ill 12

PowerShell不保持当前工作目录的.NET概念与PowerShell工作目录的概念同步的原因是:

  1. PowerShell工作目录可以在甚至不是基于文件系统的提供程序中,例如HKLM:\ Software
  2. 单个PowerShell进程可以具有多个运行空间.每个运行空间可以cd'd到不同的文件系统位置.但是,.NET /进程"工作目录"本质上是该进程的全局,并且不适用于可以有多个工作目录(每个运行空间一个)的场景.

  • @RogerLipscombe PowerShell.exe使用多个运行空间但PowerShell引擎提供的功能并不是很常见的AFAICT.PowerShell_ISE和PowerGUI等其他主机在单个进程中利用多个运行空间.启动ISE,按Ctrl + T(新的powershell选项卡)并在每个选项卡中运行$ pid,然后运行$ ExecutionContext.Host.Runspace.InstanceId.请注意,进程标识相同,但运行空间标识不同. (3认同)

Rog*_*mbe 7

为了方便起见,我将以下内容添加到我的prompt函数中,以便它在命令完成时运行:

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

这不一定是个主意,因为这意味着某些脚本(假设 Win32 工作目录跟踪 PowerShell 工作目录)可以在我的计算机上运行,​​但不一定在其他计算机上运行。