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

半世苍凉 提交于 2019-12-07 08:10:09

问题


I'm noticing a VERY odd behavior in both my PS ISE and PS when I'm getting a FileInfo object by calling

$FileInfo = [System.IO.FileInfo](".\SomeFile.ext")

When I look at its properties the DirectoryName and its related properties all default to the ORIGINAL path that PS opens in.

Here's a copy from my ISE which launches as an administrator with c:\Windows\System32 as the default path

If I run the following code:

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

I get

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\system32\7za.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

With my regular account it defaults to my H:\ path so the same test would have H:\ as the DirectoryName.

And yes, each of these files ONLY exists in the directory it was relative to.

Has anyone seen this before, and do they know a good fix? Using fully qualified of course works but this is for a script that other technicians might run and we're all pretty used to the idea of using relative pathing with PS.


回答1:


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.

  • From http://www.beefycode.com/post/The-Difference-between-your-Current-Directory-and-your-Current-Location.aspx

and

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)

  • From http://www.leeholmes.com/blog/2006/07/18/set-location-and-environmentcurrentdirectory/


来源:https://stackoverflow.com/questions/33309256/in-powershell-why-does-casting-to-fileinfo-set-the-wrong-fullname-directory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!