#powershell #dll #.net-assembly #gac #cmdlet
#powershell #dll #.net-сборка #gac #powershell-командлет
Вопрос:
У меня есть среда, в которой файлы не могут быть записаны на диск, и поэтому я обычно загружаю библиотеки 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>}
..но командлеты не экспортируются .. конечно, я наверняка что-то упускаю.
Та же библиотека DLL, загруженная «обычным» способом:
load-module AudioDeviceCmdlets.dll
корректно экспортирует несколько командлетов, таких как Get-AudioDevice и Set-AudioDevice.
Любой намек на то, какие шаги мне не хватает для предоставления командлетов в dll?
Ответ №1:
хотя это кажется очень грубым, (и я все еще открыт для лучших ответов!)это работает:
1) Выберите первый экземпляр доступной сборки (поскольку их может быть несколько, или будьте более конкретны в поиске той, которую вы хотите загрузить):
$Assembly=([System.AppDomain]::CurrentDomain.GetAssemblies()|? FullName -Match "AudioDeviceCmdlets")[0]
2) Импортируйте сборку с помощью Import-Module, но вместо указания загружаемой библиотеки dll ссылайтесь на сборку напрямую. Без манифеста по умолчанию будет экспортироваться все переменные и все содержащиеся в них функции
Import-Module -Assembly $Assembly
Вуаля, теперь командлеты экспортированы правильно! 🙂
Комментарии:
1. Нет, это правильный способ, если вам нужно сделать это в памяти (также обновил мой ответ,
Relection.Load()
возвращаетAssembly
объект, нет необходимости искать его снова) 🙂
Ответ №2:
Используйте Import-Module -Assembly
:
$assembly = [Reflection.Assembly]::Load($UncompressedFileBytes)
Import-Module -Assembly $assembly
В качестве альтернативы, создайте манифест модуля, который загружает сборку, а затем импортируйте ее:
New-ModuleManifest .AudioDeviceCmdlets.psd1 -RequiredAssemblies AudioDeviceCmdlets
Import-Module .AudioDeviceCmdlets.psd1
Комментарии:
1. ..но я не могу локально записать манифест psd1 … могу ли я загрузить его, скажем, из scriptblock?
2. У меня есть минимальный манифест: @{ RootModule = ‘AudioDeviceCmdlets . dll’ ModuleVersion = ‘3.0.0.4’ GUID = ‘7156b1c0-8e86-4d19-8df1-058c15629f36’ Автор = ‘Франсуа Гендрон <fg@frgn.ca > ‘Powersellversion = ‘3.0’ FunctionsToExport = » CmdletsToExport = » VariablesToExport = » AliasesToExport = » } но до сих пор я успешно загружал его только из файла. Нет способа загрузить его из переменной / из памяти?