views:

26

answers:

2

I am currently writing a PowerShell snapin that has specific dependencies on mixed-mode assemblies (assemblies containing native code) that specifically target x64 or x86. I have both versions of the dependent assembly, but I am wondering how best to manage the build and deployment of this snapin, specifically:

  1. Is it necessary to have two versions of the snapin, one x86 and one x64, and use the two different versions of installutil to install it, once for each architecture?
  2. Assuming #1 is true, is it recommended to install the two different versions of the snapin in the different "Program Files" and "Program Files (x86)" directories?
  3. What is the ideal (least hassle) way to structure a pair of projects that share everything but a single reference, in order to build for the two different architectures?
  4. If the snapin is compiled as "AnyCpu", and the dependent dlls are both loaded into the GAC, will the runtime load the correct assembly from the GAC based on the architecture of the currently running PowerShell host?
  5. Is there a slick way to dynamically, at run-time, choose which dependent dll to load (if it cannot, for various reasons, be installed in the GAC) without running into headaches with assembly load contexts?
+3  A: 

Mark, we have this very situation with the PowerShell Community Extensions with 32-bit and 64-bit versions of 7zip.dll. You can pretty easily work around this by PInvoking to LoadLibrary early in your snapin startup (or before you need to call out to the native DLL). You can then test if you're a 32-bit or 64-bit process (IntPtr.Size) and then load manually the correct DLL using the LoadLibrary PInvoke. After that the, DllImport("YourNative.dll") will notice that the dll is already loaded and use that DLL.

Take a look at these two PSCX source code files: http://pscx.codeplex.com/SourceControl/changeset/view/74794?ProjectName=Pscx#1358100 http://pscx.codeplex.com/SourceControl/changeset/view/74794?ProjectName=Pscx#1358102

Keith Hill
That's exactly the line of thinking I'm looking for, but I'm working with a mixed-mode assembly here, not a regular Windows .dll. I believe that means I can't just call LoadLibrary on it, correct? Also, what is this "snapin startup" you speak of? How can I run initialization code each time my snapin is added to the current shell?
Mark
I've added a separate question about the initialization code: http://stackoverflow.com/questions/3551771/how-can-i-run-initialization-code-each-time-my-snap-in-is-loaded
Mark
In that case, I wonder if you could install both 32-bit and 64-bit mixed-mode assemblies into the GAC and see if the CLR will load the correct one based on the process bitness.
Keith Hill
A: 

I ended up creating a module (thanks, Richard!), but that didn't solve the problems related to processor architecture. In order to solve that, I put both versions of the dependent dll in the module directory, and in each cmdlet's constructor I put some initialization code (that only runs once) to load the appropriate version of the dependent dll.

Thanks, all, for the pointers.

Mark