问题描述
这个问题似乎很简单,我在下面使用的方法应该可以,但是不能:
PS C:\Users\John.Smith\Downloads> rm .\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
True
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
True
我删除了文件,但是它仍然表明文件存在。我发现它正在寻找我的主目录下的文件(即使指定了“。”):
PS C:\Users\John.Smith\Downloads> rm ..\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
False
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
False
这是错误还是什么?我正在使用的OS和Powershell版本是:
PS C:\Users\John.Smith\Downloads> (Get-WmiObject -class Win32_OperatingSystem).Caption
Microsoft Windows Server 2012 R2 Standard
PS C:\Users\John.Smith\Downloads> $psversiontable.psversion
Major Minor Build Revision
----- ----- ----- --------
5 1 14409 1005
我能想到的一个解决方案是使用pwd
查找当前目录,并检查提供给我的文件是否是相对路径(不是以\或/开头),然后加入当前目录相对路径,但我认为应该有一个更简单的方法,您能帮我吗?谢谢。
解决方法
这是错误还是什么?
不,这种行为是预期的。
将相对路径作为参数的 .NET方法将相对于调用进程的工作目录来解析它们。-当您在以下位置之间导航时,powershell.exe
不会更新其当前工作目录PowerShell本身内部的位置:
PS C:\Users\John.Smith> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
PS C:\Users\John.Smith> cd Downloads
PS C:\Users\John.Smith\Downloads> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
您可以通过仅传递有根文件系统路径来解决此问题:
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("$PWD\uucode.ps1")
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists('C:\Users\John.Smith\Downloads\uucode.ps1')
...或者最好只是坚持使用PowerShell的提供程序cmdlet-在FileSystem
位置时,Test-Path -PathType Leaf
相当于[File]::Exists()
:
PS C:\Users\John.Smith\Downloads> Test-Path .\uucode.ps1 -PathType Leaf # always correctly resolves path relative to $PWD
如果您希望PowerShell始终更新主机应用程序进程的当前工作目录,则可以do so in the prompt
function
$function:prompt = {
# Need to check that we're in the file system - can't set process directory to a registry path for example
if ($PWD.Provider.Name -eq 'FileSystem') {
[System.IO.Directory]::SetCurrentDirectory($PWD)
}
return "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
}