У меня есть модуль PowerShell, написанный на C#. Поскольку модуль использует API Google, мне нужно иметь ссылку на конкретную System.Net.Http.Primitives.dll. Запуск кода на C# не вызывает проблем с загрузкой этого модуля, но в PowerShell я должен указать, какую сборку загружать, иначе будут выданы ошибки, говорящие о том, что сборка не может быть найдена.
Тем не менее, мой класс Cmdlet наследуется от IModuleAssemblyInitializer и реализует OnImport, как предложено здесь. Базовый код C# выглядит следующим образом:
public void OnImport() {
AppDomain.CurrentDomain.AssemblyResolve += ResolveSystemPrimitives;
}
private static Assembly ResolveSystemPrimitives(object sender, ResolveEventArgs args) {
Assembly accurate = Assembly.LoadFrom(System.IO.Path.Combine(AssemblyDirectory,
"System.Net.Http.Primitives.dll"));
return accurate;
}
Это работало до недавнего времени, когда кто-то сообщил, что если они сначала загрузят мой модуль, а затем попытаются загрузить другой модуль, они получат множество ошибок. Например, если вы затем попытаетесь загрузить модуль Active Directory в PowerShell:
PS C:\> Import-Module ActiveDirectory
Import-Module : The following error occurred while loading the extended type data file:
, C:\Windows\system32\WindowsPowerShell\v1.0\Modules\ActiveDirectory\ActiveDirectory.Types.ps1xml(11) : Error in type "Microsoft.ActiveDirectory.Management.ADEntity": Exception: Cannot convert the
"Microsoft.ActiveDirectory.Management.ADEntityAdapter" value of type "System.String" to type "System.Type".
...A lot more of these
Однако если вы снова откроете PowerShell и загрузите модули в обратном порядке, проблем не возникнет. Пока все, что я узнал, это то, что ошибки связаны с моей загрузкой сборки Primitives - если я это прокомментирую, мой код выйдет из строя, но все модули загружаются нормально.
Чтобы еще больше усложнить ситуацию, я попытался сделать обработчик AssemblyResolve избирательным, чтобы он загружал Primitives.dll только тогда, когда это то, что он ищет. Но когда я поставил точку останова в обработчике событий ResolveSystemPrimitives на проверьте свойство ResolveEventArgs.Name, оно было запущено только дважды, и ни одно значение не было библиотекой Primitives, а было Microsoft.PowerShell.Commands.Management и System. Управление.Ресурсы.Автоматизации.
Итак, как я могу обновить код разрешения сборки, чтобы он не нарушал дальнейший импорт модулей PowerShell? Во время тестирования это было проблемой в Windows 7 и 8.1, а также при использовании целевой сборки .Net 4.0.
Обновление. Когда я работал над набором командлетов, возникла еще одна проблема, из-за которой мой модуль Microsoft.Powershell.Management полностью исчезал из Powershell вместе со всеми основными командлетами. это обеспечивает. Сначала я думал, что это из-за моего модуля, но даже когда я не ссылался на него, все шло не так.
После нескольких перезагрузок и нескольких обращений к Import-Module Microsoft.Powershell.Management
, чтобы напомнить PoSh, что ему нужна эта сборка, все снова заработало. А потом все снова начало работать. Кажется, у меня больше нет вышеперечисленных проблем - я могу загружать модули в любом порядке без последствий, и мой обработчик AssemblyResolve фактически видит правильную ошибку сборки.
Я понятия не имею, что произошло.