Thursday, 14 October 2010

Using Maestro in native mode with MapGuide Open Source 2.2 / MapGuide Enterprise 2011 assemblies

The release of MapGuide Enterprise 2011 and the pending release of MapGuide Open Source 2.2 has slightly changed the game with regards to using Maestro with the official API

Here's how to do it with this release.

First go to the mapviewernet/bin directory of your MapGuide installation

The highlighted dlls are the .net assemblies we need to strong name. Because of RFC68, the previous MapGuideDotNetApi.dll is now split into 5 separate assemblies. The MapGuideDotNetApi.dll in this installation is now a compatibility stub that redirects to the 5 assemblies.

To be able to use these assemblies in Maestro, we need to do the following:
  • Sign all these assemblies with the Maestro public key
  • Setup binding redirection for this new version of MapGuideDotNetApi.dll in web.config/app.config
Unfortunately, the current method using Signer.exe does not work because it doesn't properly handle assemblies with TypeForwardedTo attributes (as is the case with the new MapGuideDotNetApi.dll) nor does it handle updating inter-assembly references to signed equivalents, so to actually sign these assemblies, we need to use the ildasm.exe and ilasm.exe utilities that come with the .net Framework SDK.

So first, copy the aforementioned assemblies into a temporary folder

Rename MapGuideDotNetApi.dll to MapGuideDotNetApi-2.2.dll

Now open up a SDK command prompt into this folder and issue the following commands:
  • ildasm /all / MapGuideDotNetApi-2.2.dll
  • ildasm /all / OSGeo.MapGuide.Foundation.dll
  • ildasm /all / OSGeo.MapGuide.Geometry.dll
  • ildasm /all / OSGeo.MapGuide.MapGuideCommon.dll
  • ildasm /all / OSGeo.MapGuide.PlatformBase.dll
  • ildasm /all / OSGeo.MapGuide.Web.dll
Your file listing should now look like this:

Delete the existing dll files, because ilasm.exe will rebuild them.

Before we continue, let's sidestep for a moment.

Here is a screenshot of a reflector dump of the original MapGuideDotNetApi.dll

Notice the PublicKeyToken=null part of the referenced assembly. The original MapGuideDotNetApi.dll is referencing un-signed assemblies (obviously). So when we rebuild MapGuideDotNetApi.dll with ilasm.exe, we have to make sure that it is referencing the signed versions of these assemblies, otherwise the you will get errors due to failing to locate the strongly-named assembly.

Also note that some OSGeo.MapGuide assemblies reference other OSGeo.MapGuide assemblies, thus we need to ensure that all references need to be updated. For reference, the dependency chain is as follows:
  • OSGeo.MapGuide.Foundation references nothing
  • OSGeo.MapGuide.Geometry references OSGeo.MapGuide.Foundation
  • OSGeo.MapGuide.PlatformBase references OSGeo.MapGuide.Foundation and OSGeo.MapGuide.Geometry
  • OSGeo.MapGuide.MapGuideCommon references OSGeo.MapGuide.Foundation, OSGeo.MapGuide.Geometry and OSGeo.MapGuide.PlatformBase
  • OSGeo.MapGuide.Web references OSGeo.MapGuide.Foundation, OSGeo.MapGuide.Geometry and OSGeo.MapGuide.PlatformBase

Download a copy of the maestroapi.key into this directory.

Now in the same command prompt, rebuild and sign the OSGeo.MapGuide.Foundation assembly using ilasm.exe:
  • ilasm /dll /key=maestroapi.key

Take a look at this assembly in reflector.

Note the public key token, it will be the same for the other signed assemblies that we will sign. We need to update the IL of MapGuideDotNetApi and others to include this public key token in their assembly references.

Open the in a text editor.

Locate the relevant section for the IL files of the other assemblies and update them with the same public key token. Once that is done, rebuild and sign them all with ilasm.exe
  • ilasm /dll /key=maestroapi.key
  • ilasm /dll /key=maestroapi.key
  • ilasm /dll /key=maestroapi.key
  • ilasm /dll /key=maestroapi.key
  • ilasm /dll /key=maestroapi.key
Your assemblies are now properly signed and referencing the signed versions of their needed assemblies.

Now these are ready to be used in Maestro.

Copy all the files from mapviewernet/bin (except for MapGuideDotNetApi.dll) into your Maestro installation.

Now copy all the signed assemblies from our temp directory into your Maestro installation, overwrite the existing assemblies with our signed ones.

Now edit your app.config/web.config to redirect the currently referenced MapGuideDotNetApi.dll to our signed version:

And Maestro in Native mode will correctly use the assemblies we just signed.

Note that for MapGuide Enterprise 2011, the assembly version number is different but the process is the same.

Upon the proper release of MapGuide Open Source 2.2, I'll post the signed assemblies here so you won't have to follow this long process :D