在 PowerShell 中,为什么 "casting" 到 FileInfo 设置了错误的 FullName、Directory 和 DirectoryName

In PowerShell why does "casting" to FileInfo set the wrong FullName, Directory, and DirectoryName

当我通过调用

获得 FileInfo 对象时,我注意到我的 PS ISE 和 PS 有一个非常奇怪的行为
$FileInfo = [System.IO.FileInfo](".\SomeFile.ext")

当我查看其属性时,DirectoryName 及其相关属性都默认为 PS 打开的原始路径。

这是我的 ISE 的一个副本,它以管理员身份启动,c:\Windows\System32 作为默认路径

如果我运行下面的代码:

$Fileinfo = [System.IO.FileInfo](".\@OpenWithToastLogo.png")  
cd c:\temp  
$Fileinfo2 = [System.IO.FileInfo](".\activation.txt")  
z:  
$Fileinfo3 = [System.IO.FileInfo](".za.exe")  
$Fileinfo | fl *
$Fileinfo2 | fl *
$Fileinfo3 | fl *

我明白了

VersionInfo :
File : C:\WINDOWS\system32\@OpenWithToastLogo.png
InternalName :
OriginalFilename :
FileVersion :
FileDescription :
Product :
ProductVersion :
Debug : False
Patched : False
PreRelease : False
PrivateBuild : False
SpecialBuild : False
Language :
BaseName : @OpenWithToastLogo
Target : {C:\Windows\WinSxS\wow64_microsoft-windows-openwith_31bf3856ad364e35_10.0.10240.16384_none_7f75eaad41c1f239\@OpenWithToastLogo.png,C:\Windows\SysWOW64\@OpenWithToastLogo.png}
LinkType : HardLink
Mode : -a---l
Name : @OpenWithToastLogo.png
Length : 160
DirectoryName : C:\WINDOWS\system32
Directory : C:\WINDOWS\system32
IsReadOnly : False
Exists : True
FullName : C:\WINDOWS\system32\@OpenWithToastLogo.png
Extension : .png CreationTime : 7/10/2015 7:00:32 AM
CreationTimeUtc : 7/10/2015 11:00:32 AM
LastAccessTime : 7/10/2015 7:00:32 AM
LastAccessTimeUtc : 7/10/2015 11:00:32 AM
LastWriteTime : 7/10/2015 7:00:32 AM
LastWriteTimeUtc : 7/10/2015 11:00:32 AM
Attributes : Archive

VersionInfo :
BaseName : activation Target :
LinkType :
Mode : darhsl
Name : activation.txt
Length :
DirectoryName : C:\WINDOWS\system32
Directory : C:\WINDOWS\system32
IsReadOnly : True
Exists : False
FullName : C:\WINDOWS\system32\activation.txt
Extension : .txt
CreationTime : 12/31/1600 7:00:00 PM
CreationTimeUtc : 1/1/1601 12:00:00 AM
LastAccessTime : 12/31/1600 7:00:00 PM
LastAccessTimeUtc : 1/1/1601 12:00:00 AM
LastWriteTime : 12/31/1600 7:00:00 PM
LastWriteTimeUtc : 1/1/1601 12:00:00 AM
Attributes : -1

VersionInfo :
BaseName :
7za Target :
LinkType :
Mode : darhsl
Name : 7za.exe
Length :
DirectoryName : C:\WINDOWS\system32
Directory : C:\WINDOWS\system32
IsReadOnly : True
Exists : False
FullName : C:\WINDOWS\system32za.exe
Extension : .exe
CreationTime : 12/31/1600 7:00:00 PM
CreationTimeUtc : 1/1/1601 12:00:00 AM LastAccessTime : 12/31/1600 7:00:00 PM
LastAccessTimeUtc : 1/1/1601 12:00:00 AM
LastWriteTime : 12/31/1600 7:00:00 PM
LastWriteTimeUtc : 1/1/1601 12:00:00 AM
Attributes : -1

对于我的常规帐户,它默认为我的 H:\ 路径,因此相同的测试将 H:\DirectoryName.

是的,这些文件中的每一个都只存在于它的相对目录中。

有没有人以前见过这个,他们知道一个好的解决办法吗?使用完全限定当然可行,但这是针对其他技术人员可能 运行 的脚本,我们都非常习惯使用 PS.

的相对路径的想法

PowerShell has a notion of your current location. You can see this using the $pwd automatic variable or the Get-Location cmdlet [..]

This path is used by PowerShell to resolve relative paths at the level of the PowerShell API.

[..]

Applications have a notion of the current directory. This is the directory used to resolve relative paths at the level of the Windows API.

How you Get Burned

Your current location may or may not be the same as your current directory.

One question that comes up frequently is, “Why does PowerShell not change its [System.Environment]::CurrentDirectory as I navigate around the shell?”

One of the difficult aspects of this comes from the fact that PowerShell supports multiple pipelines of execution. Although it’s not directly exposed yet, users will soon be able to suspend jobs to the background, and other concurrent tasks.

The current directory affects the entire process, so if we change the directory as you navigate around the shell, you risk corrupting the environment of jobs you have running in the background.

When you use filenames in .Net methods, the best practice is to use fully-qualified path names. The Resolve-Path cmdlet makes this easy:

$reader = new-object System.Xml.XmlTextReader (Resolve-Path baseline.xml)