Получение целевого атрибута платформы в PowerShell Core - PullRequest
0 голосов
/ 17 февраля 2019

Я ищу способ извлечь атрибут целевой структуры (например, .NETCoreApp,Version=v2.1) из DLL при использовании PowerShell Core , в идеале без загрузки DLL непосредственно в основной сеанс.

Я могу сделать это в Windows PowerShell 5, поскольку у него есть доступ к методу ReflectionOnlyLoadFrom ...

$dllPath = 'C:\Temp\ADALV3\microsoft.identitymodel.clients.activedirectory.2.28.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll'

[Reflection.Assembly]::ReflectionOnlyLoadFrom($dllPath).CustomAttributes |
Where-Object {$_.AttributeType.Name -eq 'TargetFrameworkAttribute'} |
Select -ExpandProperty ConstructorArguments |
Select -ExpandProperty value

Однако я понимаю, что этот подход недоступно в .NET Core.

Примечание редактора : даже если документация (на момент написания этой статьи) вводит в заблуждение, что метод ReflectionOnlyLoadFrom доступно в .NET Core, не , как объяснено здесь .

Из того, что я видел, это выглядит вероятнымчто я должен иметь возможность доступа к пользовательским атрибутам, которые содержат целевой атрибут инфраструктуры, используя экземпляр класса System.Reflection.Metadata.MetadataReader, который доступен в .NET Core (пару примеров этого в использовании можно найти здесь: https://csharp.hotexamples.com/examples/System.Reflection.Metadata/MetadataReader/GetCustomAttribute/php-metadatareader-getcustomattribute-method-examples.html).Однако все конструкторы для этого типа, похоже, используют тип Byte*, как показано ниже при запуске из PowerShell Core:

([type] 'System.Reflection.Metadata.MetadataReader').GetConstructors() | % {$_.GetParameters() | ft}

Я понятия не имею, как создать тип Byte* в любомверсия PowerShell.Возможно, в System.Reflection.Metadata есть метод, который мне следует использовать перед созданием объекта MetadataReader, но я его пока не нашел.

Извиняюсь за длину этого вопроса, но я надеюсь поделиться своимзаметки я помогу в поиске решения.Любой совет о том, как получить эту информацию целевой структуры с помощью PowerShell Core?

1 Ответ

0 голосов
/ 20 февраля 2019

После долгой работы мне удалось собрать сценарий PowerShell, который работает (без внешних зависимостей) в PowerShell Core, который извлекает целевую среду из DLL:

$dllPath = 'C:\Temp\ADALV3\microsoft.identitymodel.clients.activedirectory.2.28.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll'

$stream = [System.IO.File]::OpenRead($dllPath)

$peReader = [System.Reflection.PortableExecutable.PEReader]::new($stream, [System.Reflection.PortableExecutable.PEStreamOptions]::LeaveOpen -bor [System.Reflection.PortableExecutable.PEStreamOptions]::PrefetchMetadata)

$metadataReader = [System.Reflection.Metadata.PEReaderExtensions]::GetMetadataReader($peReader)

$assemblyDefinition = $metadataReader.GetAssemblyDefinition()

$assemblyCustomAttributes = $assemblyDefinition.GetCustomAttributes()

$metadataCustomAttributes = $assemblyCustomAttributes | % {$metadataReader.GetCustomAttribute($_)}

foreach ($attribute in $metadataCustomAttributes) {

    $ctor = $metadataReader.GetMemberReference([System.Reflection.Metadata.MemberReferenceHandle]$attribute.Constructor)
    $attrType = $metadataReader.GetTypeReference([System.Reflection.Metadata.TypeReferenceHandle]$ctor.Parent)
    $attrName = $metadataReader.GetString($attrType.Name)
    $attrValBytes = $metadataReader.GetBlobContent($attribute.Value)
    $attrVal = [System.Text.Encoding]::UTF8.GetString($attrValBytes)

    if($attrName -eq 'TargetFrameworkAttribute') {Write-Output "AttributeName: $attrName, AttributeValue: $attrVal"}

}

$peReader.Dispose()

Яв основном доволен этим, единственная проблема, которую я все еще хотел бы решить, это то, что я получаю некоторые необработанные символы в выводе строки.Я постараюсь избавиться от них.

Current script output

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