.net “在哪里?”;“目标”;System.IO.FileInfo的成员是否记录在案?

.net “在哪里?”;“目标”;System.IO.FileInfo的成员是否记录在案?,.net,powershell,.net,Powershell,PowerShell命令letGet 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\amd

PowerShell命令let
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的文档中没有提到该成员/属性 以及它的基类

我怀疑
Target
的值是连接点、符号或硬链接指向的某种类型-但是,如果我在目标文件上应用
Target
,我会再次获得原始文件:

PS C:\> (get-item $item.Target).Target
C:\Windows\System32\atl.dll

那么,这个
目标成员是什么?

tl;博士

  • 没有ETS(扩展型系统)成员的文档,如
    .Target

  • c:\windows\System32\atl.dll
    是指向同一文件数据的两种所谓的方法之一(另一种是
    c:\windows\WinSxS\amd64\u microsoft-windows-atl\u 31bf3856ad364e35\u 10.0.18362.1\u none\u 7d7dafc1d6eadbc7\atl.dll

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


正如Mathias R.Jessen指出的那样,
.Target
属性是一个属性—由PowerShell添加的一个属性,用于扩展本机.NET类型的功能

没有此类ETS成员的文档(可能还包括方法),您的最佳选择是研究他们的定义,这不能保证为您提供完整的故事,也不能保证您只需付出不小的努力:

在第一步中,您可以使用cmdlet检查
.Target
属性的定义(该属性同时添加到
System.IO.FileInfo
System.IO.DirectoryInfo
实例):

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

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

  • 在Windows PowerShell中,考虑到其源代码不公开,这就到此为止了

  • 在PowerShell[Core]6+中,您可以检查中的源代码,尤其是文件中的源代码(此链接是永久链接,随着时间的推移将变得过时;单击页面顶部的
    分支:
    下拉列表切换到当前的
    主分支

下面讨论
.Target
的部分推断行为


.Target
的目的和行为:
  • .Target
    属性返回文件系统重分析点(Windows)/symlink(symbol link;Unix)的目标路径。[1]

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

Windows PowerShell和PowerShell[Core]6+(从PowerShell 7.0开始)之间的
.Target
的行为有一个重要区别:

  • 在Windows PowerShell中,
    .Target
    返回目标路径的枚举,这意味着可以返回多个路径,仅当输入路径是同一文件(数据)的多个路径之一时才适用

    • 具体而言,硬链接的
      .Target
      属性报告存在于该文件的所有其他硬链接(即,不包括输入路径)

    • 这解释了为什么给定一个具有两个硬链接的文件,它们的
      .Target
      属性指向相应的其他路径,例如硬链接
      C:\Windows\System32\atl.dll
      指向的文件就是这样

  • 在PowerShell[Core]中,
    .Target
    仅每个返回一个路径,因为已删除对硬链接的支持-请参阅

    • 顺便提一下:与Windows不同,类Unix平台不支持枚举硬链接,因此查找到给定文件的所有硬链接既麻烦又慢


[1] 除此之外,类Unix平台只有,而在Windows上,类别不仅包括符号链接,还包括连接点、卷装入点,在最新的Windows版本中还包括AppX重分析点(Microsoft Store应用程序的应用程序执行别名).

它来自
$PSHOME\typesv3.ps1xml
只需使用
Get Member
好的,我知道
Target
来自哪里,但为什么每个目标都指向彼此的目标仍然是个谜。
# 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]
[...]