在哪里可以找到 System.IO.FileInfo 中的 "Target" 成员文档?

4
PowerShell命令行工具中,如果应用于一个文件的Get-Item命令返回System.IO.FileInfo类型。
PS C:\> $item = get-item c:\windows\System32\atl.dll
PS C:\> $item.GetType().FullName
System.IO.FileInfo

使用标签卡在$item上,我发现它有一个名为Target的成员/属性:

PS C:\> $item.Target
C:\Windows\WinSxS\amd64_microsoft-windows-atl_31bf3856ad364e35_10.0.18362.1_none_7d7dafc1d6eadbc7\atl.dll

然而,在 Microsoft 的文档System.IO.FileInfo及其基类System.IO.FileSystemInfo中,没有提到该成员或属性。
我怀疑Target的值是符号链接或硬链接指向的位置,但如果我将其应用于目标文件,则会再次得到原始文件。
PS C:\> (get-item $item.Target).Target
C:\Windows\System32\atl.dll

那么,这个 Target 成员是什么?


1
这是一个ETS CodeProperty,它来自于$PSHOME\typesv3.ps1xml - Mathias R. Jessen
只需使用 Get-Member - RoadRunner
好的,我理解 Target 是从哪里来的了,但每个目标为什么都指向彼此的目标仍然是个谜。 - René Nyffenegger
1个回答

2
简述:
  • ETS(扩展类型系统)成员(如.Target)没有文档。

  • c:\windows\System32\atl.dll是两个所谓的硬链接之一,它们指向相同的文件数据(另一个是C:\Windows\WinSxS\amd64_microsoft-windows-atl_31bf3856ad364e35_10.0.18362.1_none_7d7dafc1d6eadbc7\atl.dll)。

    • 对于硬链接,.Target报告所有其他硬链接(指向同一文件的路径),这就是为什么两个项目的.Target属性值分别指向另一个路径的原因。
  • 您的代码在PowerShell [Core]中不再起作用,因为通过.Target报告硬链接的支持已被删除 - 请参阅this GitHub issue


如Mathias R. Jessen所指出的那样,.Target属性是ETS(扩展类型系统)属性——PowerShell添加的一种属性,用于扩展本机.NET类型的功能。
这些ETS成员(也可能包括方法)没有文档可供参考——您最好的选择是研究它们的定义,但这并不能保证您能获得完整的信息,或者需要付出相当大的努力:
首先,您可以使用Get-TypeData cmdlet来检查.Target属性的定义(该属性添加到System.IO.FileInfoSystem.IO.DirectoryInfo实例中)。
# Windows PowerShell
PS> (Get-TypeData System.IO.FileInfo).Members.Target | foreach GetCodeReference

Name                       : GetTarget
DeclaringType              : Microsoft.PowerShell.Commands.InternalSymbolicLinkLinkCodeMethods
[...]
MemberType                 : Method
ReturnType                 : System.Collections.Generic.IEnumerable`1[System.String]
[...]

"

Get-Item $PROFILE | Get-Member Target也可以用,但在这种情况下缺少重要信息:属性.TargetCodeProperty类型,即其值由调用.NET类型的静态方法确定,但输出的.Definition属性仅显示该方法为 Target{get=GetTarget;};即完整的类型名丢失了。

也就是说,使用手头的System.IO.DirectoryInfo实例调用[Microsoft.PowerShell.Commands.InternalSymbolicLinkLinkCodeMethods]::GetTarget()来返回该实例的.Target属性值。

"
  • Windows PowerShell 中,由于其源代码不是公开的,这是行末。

  • 在 PowerShell [Core] 6+ 中,您可以查看 GitHub 存储库 中的源代码,特别是文件 FileSystemProvider.cs(此链接是永久链接,随时间而过时;单击页面顶部的 Branch: 下拉列表切换到当前的 master 分支)。

接下来讨论了 .Target 的部分推断行为。


.Target的目的和行为:

  • .Target属性返回文件系统的重解析点(Windows)/ 符号链接(symbolic link's;Unix)目标路径。[1]

  • 如果输入路径不是重解析点或符号链接,则.Target返回“nothing”:具体来说,是[System.Management.Automation.Internal.AutomationNull] ::Value(Windows PowerShell;在大多数情况下的行为类似于$null)/ $null(PowerShell [Core])。

.Target在Windows PowerShell和PowerShell [Core] 6+(PowerShell 7.0)之间的行为有重要的差异:

在Windows PowerShell中,.Target返回一个目标路径的枚举,这意味着可能会返回多个路径,仅当输入路径是指向同一文件(数据)的几个硬链接之一时才适用。
具体来说,硬链接的.Target属性报告了所有存在于该文件的其他硬链接(即不包括输入路径)。
这就解释了为什么对于具有两个硬链接的文件,它们的.Target属性指向各自的另一个路径,例如指向硬链接C:\Windows\System32\atl.dll所指向的文件。
在PowerShell [Core]中,.Target仅返回一个单一路径,因为已删除对硬链接的支持 - 参见this GitHub issue
顺便说一下:与Windows不同,类Unix平台没有系统级别的支持来枚举硬链接,因此查找给定文件的所有硬链接既麻烦又慢。
除了硬链接之外,类Unix平台只有符号链接,而在Windows上,重新解析点的类别不仅包括符号链接,还包括连接点、卷挂载点以及在最近的Windows版本中出现的AppX重新解析点(用于Microsoft Store应用程序的应用执行别名)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接