Экспорт CMDlet Powershell из библиотек DLL, загруженных с помощью [Reflection.Assembly] :: Load () - PullRequest
1 голос
/ 18 апреля 2019

У меня есть среда, в которой файлы не могут быть записаны на диск, и поэтому я обычно загружаю DLL из памяти в GAC.

Хотя загрузка не является проблемой, разоблачение командлетов DLL происходит.Сборка загружена:

[appdomain]::currentdomain.getassemblies() | sort -property fullname | format-table fullname

FullName
--------
AudioDeviceCmdlets, Version=3.0.0.4, Culture=neutral, PublicKeyToken=null

fl *

CodeBase            : file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_64/mscorlib/v4.0_4.0.0.0__b77a5c561934e089/mscorlib.dll
FullName            : AudioDeviceCmdlets, Version=3.0.0.4, Culture=neutral, PublicKeyToken=null
EntryPoint          :
DefinedTypes        : {CoreAudioApi.AudioEndpointVolume, CoreAudioApi.AudioEndpointVolumeCallback, CoreAudioApi.AudioEndpointVolumeChannel, CoreAudioApi.AudioEndpointVolumeChannels...}
Evidence            : {<System.Security.Policy.Url version="1">
                      <Url>file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_64/mscorlib/v4.0_4.0.0.0__b77a5c561934e089/mscorlib.dll</Url>
                      </System.Security.Policy.Url>
                      , <System.Security.Policy.Zone version="1">
                      <Zone>MyComputer</Zone>
                      </System.Security.Policy.Zone>
                      }
PermissionSet       : {}
SecurityRuleSet     : Level2
ManifestModule      : AudioDeviceCmdlets.dll
ReflectionOnly      : False
Location            :
ImageRuntimeVersion : v4.0.30319
GlobalAssemblyCache : False
HostContext         : 0
IsDynamic           : False
EscapedCodeBase     : file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_64/mscorlib/v4.0_4.0.0.0__b77a5c561934e089/mscorlib.dll
ExportedTypes       : {CoreAudioApi.AudioEndpointVolume, CoreAudioApi.AudioEndpointVolumeChannel, CoreAudioApi.AudioEndpointVolumeChannels, CoreAudioApi.AudioEndpointVolumeNotificationDelegate...}
IsFullyTrusted      : True
CustomAttributes    : {[System.Runtime.CompilerServices.CompilationRelaxationsAttribute((Int32)8)], [System.Runtime.CompilerServices.RuntimeCompatibilityAttribute(WrapNonExceptionThrows = True)],
                      [System.Diagnostics.DebuggableAttribute((System.Diagnostics.DebuggableAttribute+DebuggingModes)2)], [System.Reflection.AssemblyTitleAttribute("AudioDeviceCmdlets")]...}
Modules             : {<unknown>}

.. но CMDLets не экспортируются ... конечно, я наверняка что-то упускаю.

Та же DLL, загруженная «обычным» способом:

load-module AudioDeviceCmdlets.dll

корректно экспортирует несколько CmdLets, например Get-AudioDevice и Set-AudioDevice .

Любой намек на какие шаги я пропускаю, чтобы выставить Командлеты в DLL?

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

, хотя это кажется очень грубым, (и я все еще открыт для лучших ответов!) это работает:

1) Выберите первый экземплярДоступная сборка (так как их может быть больше одной или, если быть более точным, найти ту, которую вы хотите загрузить):

$Assembly=([System.AppDomain]::CurrentDomain.GetAssemblies()|? FullName -Match "AudioDeviceCmdlets")[0]

2) Импортируйте сборку с помощью Import-Module, но вместо указания библиотеки DLLчтобы загрузить, обратитесь к сборке напрямую. Без манифеста по умолчанию будет экспортироваться все переменные и все содержащиеся в нем функции

Import-Module -Assembly $Assembly

Вуаля, теперь командлеты корректно экспортируются!:)

1 голос
/ 18 апреля 2019

Используйте Import-Module -Assembly:

$assembly = [Reflection.Assembly]::Load($UncompressedFileBytes)    
Import-Module -Assembly $assembly

Либо создайте манифест модуля, который загружает сборку, а затем импортируйте:

New-ModuleManifest .\AudioDeviceCmdlets.psd1 -RequiredAssemblies AudioDeviceCmdlets
Import-Module .\AudioDeviceCmdlets.psd1
...