I have a PowerShell module that is written in C#. As a result of the the module using the Google APIs, I need to have a specific System.Net.Http.Primitives.dll referenced. Running the code in C# has no issues loading that module, but in PowerShell I must specify which assembly to load or it will throw errors saying that assembly couldn't be found.
That said, my Cmdlet class inherits from IModuleAssemblyInitializer and implements the OnImport method as suggested here. The underlying C# code looks like this:
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;
}
This has been working until recently when someone reported that if they load my module first and then try to load another module, they get a slew of errors. For instance, if you then try to load the Active Directory module in 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
However, if you reopen PowerShell and load the modules in the opposite order, there is no issue. So far, all I've found out is that the errors are related to my loading of the Primitives assembly - if I comment that out, my code fails but the modules all load fine.
To further complicate things, I tried making the AssemblyResolve handler be selective so that it only will load the Primitives.dll when that's what it's looking for. But, when I threw a breakpoint on the event handler ResolveSystemPrimitives to check the ResolveEventArgs.Name property, it only was fired twice and neither value was the Primitives library, instead it was Microsoft.PowerShell.Commands.Management and System.Management.Automation.resources.
So, how can I update my Assembly Resolution code to prevent it from breaking further PowerShell module imports? At the time of testing this has been an issue on Windows 7 and 8.1, and using a .Net 4.0 target build.
Update - As I was working on the set of Cmdlets another issue came up where my Microsoft.Powershell.Management module would go missing from Powershell entirely, along with all the basic Cmdlets it provides. At first I thought it was due to my module, but even when not referencing it things were going wrong.
After a few reboots and a few calls to Import-Module Microsoft.Powershell.Management
to remind PoSh that it needs that assembly, things started working again. And then everything started working again. I no longer seem to have the above issues at all - I can load modules in any order without repercussion, and my AssemblyResolve handler is actually seeing the proper assembly error.
I have no idea what happened.