Monday, May 12, 2008

How I found out that mixed mode is cool

We ship a DDEX provider with Connector/Net.  This provider plugs into Visual Studio and integrates into server explorer allowing a user to create data connections to MySQL from within the IDE.  This integration is handled, in large part, by a lengthy series of registry entries.  Until 5.2.2, these entries were made by my installer which is written in WiX.  Having the registry changes made in the installer has two problems.  First, I often need to register the provider during debugging and I don't want to do a full install of the product so I end up hand editing a registry file and manually merging that file.  This a awkward at best.  Second I plan to ship a stand-alone configuration utility in 5.3 that will allow the user to configure which installed version of Connector/Net should be used for VS integration. Currently you can only have one instance installed at a time.

My approach to solving this was to write an installer class that made the registry changes for me and just use installutil to register the assembly.  I was already doing this with my core and web assemblies so this is nothing new.  The problem is that installutil will scan the assembly and all referenced assemblies for types looking for installer classes.  This fails when some of the Microsoft assemblies are scanned.  After much effort I gave up and decided to write my own installutil that I would ship with my installer. 

I had no trouble creating this application and then set about executing it from within my installer.  I attempted to use the CAQuietExec custom action available with WiX v3 but just couldn't make it work right.  So I gave up and decided to write my own execute custom action.

So I cracked open Visual Studio 2008 and read a couple of blogs about custom action writing.  One of them mentioned mixing managed and unmanaged code, the unmanaged code being necessary for the proper DLL exports.  I decided I had to see this work.

Within minutes I had a DLL project setup with the /clr option and had hacked out the following code:

   1: extern "C" __declspec(dllexport) UINT InstallAssembly(MSIHANDLE hMSI)


   2: {


   3:     System::Windows::Forms::MessageBox::Show("boo");


   4:     TCHAR name[261]={0};


   5:     DWORD len=261;


   6:  


   7:     UINT result = ::MsiGetProperty(hMSI, TEXT("CustomActionData"), name, &len);


   8:     InstallVSAssembly(name, true);


   9:     return ERROR_SUCCESS;


  10: }


  11:  


  12: bool InstallVSAssembly(char *assemblyName)


  13: {


  14:     String^ str = gcnew String(assemblyName);


  15:     bool uninstalling = false;


  16:     IDictionary mySavedState = new Hashtable();


  17:     int arg = 0;


  18:  


  19:     InstallContext context = new InstallContext();


  20:     while (arg < args.Length)


  21:     {


  22:         string[] parts = args[arg++].Split('=');


  23:         context.Parameters.Add(parts[0], parts[1]);


  24:     }


  25:  


  26:     Installer installer = null;


  27:     try


  28:     {


  29:         Assembly assem = Assembly.LoadFrom(file);


  30:         installer = (Installer)assem.CreateInstance("MySql.Data.VisualStudio.MyInstaller");


  31:         if (installer == null)


  32:         {


  33:             Console.WriteLine("Unable to find an installer in that assembly.");


  34:             return;


  35:         }


  36:         installer.Context = context;


  37:         if (uninstalling)


  38:             installer.Uninstall(mySavedState);


  39:         else


  40:             installer.Install(mySavedState);


  41:     }


  42:     catch (Exception e)


  43:     {


  44:         Console.WriteLine(e.Message);


  45:     }


  46:     return true;


47: }





Yes, that is managed code and unmanaged code *in the same function*!  Now this code might not compile as it is not what I wound up using and I just grabbed it out of an old folder but you get the idea (and yes I did test a version of this so I know the concept works).  I didn't use this approach because the /clr switch requires the dynamic CRT and I didn't feel like bundling that up.



And, in case you were wondering about the "boo" messagebox on line 3, that is my debugging trap.  You run the installer until that pops up, attach to the proper msiexec using Visual Studio, set a break point, and go.  Yup, that's cool.

21 comments:

  1. busby seo challengeAugust 27, 2008 at 12:07 PM

    this nice code for assembler.. now i notice is still working with it...

    ReplyDelete
  2. now i notice is still working with it... wow

    ReplyDelete
  3. Busby SEO Test PinayDecember 19, 2008 at 2:59 AM

    Thank you for that very helpful explanation.

    ReplyDelete
  4. busby seo test caseJanuary 16, 2009 at 7:59 PM

    thanks for the code ...

    ReplyDelete
  5. busby seo test postJanuary 19, 2009 at 12:07 PM

    what agreat code, thank you

    ReplyDelete
  6. Thanks for the code.

    ReplyDelete
  7. This is a great code. Thanks for sharing it.

    ReplyDelete
  8. Cirurgia PlasticaMarch 19, 2009 at 7:25 PM

    now i notice is still working with it... wow

    ReplyDelete
  9. Healthy Weight Loss PlanApril 1, 2009 at 2:38 PM

    Implementing a DDEX provider requires that you implement certain required procedures. In addition, you can implement optional procedures. The topics included in this section provide guidance on implementing a DDEX provider under various circumstances and in different implementation scenarios.

    ReplyDelete
  10. Online Casino GuideApril 2, 2009 at 9:28 PM

    The Windows Installer XML toolset (WiX, pronounced "wicks"), is a free software toolset that builds Windows Installer (MSI) packages from an XML document. It supports a command-line environment that developers may integrate into their build processes to build MSI and MSM setup packages. This is the first software released by Microsoft under an open-source license called Common Public License.

    ReplyDelete
  11. get Blue's error nukerApril 25, 2009 at 1:07 PM

    This post was really great explanation of this issue!
    Regards Matty

    ReplyDelete
  12. How to make a worm farmMay 31, 2009 at 6:40 PM

    You provided exactly what I was looking for!

    ReplyDelete
  13. tennis elbow exercisesJune 5, 2009 at 3:18 AM

    now i notice is still working with it... wow

    ReplyDelete
  14. I cracked open Visual Studio 2008 and read a couple of blogs about custom action writing. One of them mentioned mixing managed and unmanaged code, the unmanaged code being necessary for the proper DLL exports. I decided I had to see this work.

    ReplyDelete
  15. Las Vegas Real Estate InvestingJune 28, 2009 at 3:10 PM

    Mixed mode was always cool :)

    ReplyDelete
  16. record myspace musicJuly 6, 2009 at 2:18 PM

    zi jin mian

    ReplyDelete
  17. Would you like to post a guest post on my blog?

    ReplyDelete
  18. Thank you for sharing this blog post. I've bookmarked the page :)

    ReplyDelete
  19. Italian Translation ServiceSeptember 6, 2009 at 12:26 PM

    Now this is hghly recommeded post for me. I will surely email this to my friend.


    Regards

    paul

    ReplyDelete