Где задокументирован «целевой» элемент System.IO.FileInfo? - PullRequest
3 голосов
/ 12 апреля 2020

Командлет 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 - это своего рода точка, на которую указывает соединение или символ c или жесткая ссылка - пока, если я применю Target к цели, файл, я снова получаю исходный файл:

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

Итак, что это за Target член?

1 Ответ

2 голосов
/ 13 апреля 2020

tl; dr :

  • Нет документации для членов 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 - см. эту проблему GitHub .


Как указывает Матиас Джессен, свойство .Target является ETS (система расширенного типа) свойство - свойство, добавленное PowerShell для расширения возможностей собственного типа. NET.

Для таких членов ETS имеется документация * (которая h также может включать методы ) - ваша лучшая ставка - изучить их определение , которое не гарантирует вам полную историю или только с нетривиальным количество усилий:

На первом этапе вы можете использовать командлет Get-TypeData, чтобы проверить определение свойства .Target (которое добавляется к System.IO.FileInfo и System.IO.DirectoryInfo instance):

# 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 также может использоваться, но в этом случае отсутствует важная информация: свойство .Target имеет тип CodeProperty, т.е. свойство, значение которого определено при вызове метода stati c типа. NET, но свойство .Definition вывода показывает метод только как Target{get=GetTarget;}; то есть полное имя типа отсутствует ).

То есть вызов [Microsoft.PowerShell.Commands.InternalSymbolicLinkLinkCodeMethods]::GetTarget() с экземпляром System.IO.DirectoryInfo используется для возврата свойства .Target этого экземпляра значение.

  • В Windows PowerShell , это конец строки, учитывая, что его исходный код не является общедоступным.

  • В PowerShell [Core] 6+ вы можете просмотреть исходный код в GitHub репозитории , особенно в файле FileSystemProvider.cs (эта ссылка является постоянной ссылкой) , который со временем устареет; щелкните раскрывающийся список Branch: в верхней части страницы, чтобы переключиться на текущую ветку master.

Частично выведенное поведение .Target обсуждается далее.


.Target Цель и поведение:

  • Свойство .Target возвращает файловую систему точка повторной обработки (Windows) / символическая ссылка (символические c ссылки; Unix) целевые пути (и). [1]

  • Если в t path не точка повторной обработки или символическая ссылка, .Target возвращает "ничто": в частности, [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 только каждый возвращает одиночный путь потому что удалена поддержка жестких ссылок - см. эту проблему GitHub .

    • В качестве отступления: в отличие от Windows, Unix -подобные платформы не поддерживают системный уровень для перечисления жестких ссылок, поэтому поиск всех жестких ссылок на данный файл является громоздким и медленным.

[1] Помимо жестких ссылок , Unix -подобных платформ имеют только символов c ссылок , тогда как в Windows категория точек повторной обработки включает в себя не только символические c ссылки, но также соединения , точки монтирования тома , и в последних Windows версиях точки повторной обработки AppX (псевдонимы выполнения приложений для приложений Microsoft Store).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...