Including MSMQ as a prerequisite for my application

Adam Robinson picture Adam Robinson · Mar 25, 2009 · Viewed 7.7k times · Source

I'm working on an application that uses MSMQ for interprocess communication, and I need the setup project to be able to install the service if it isn't already. I've checked around for information on making it a prerequisite, but so far I've been unsuccessful at finding this. Any ideas?

Answer

Adam Robinson picture Adam Robinson · Mar 26, 2009

Discovered the answer on my own...the windows component installer is not crippled by the typical inability to install more than one MSI at any given time, so I'm able to use a custom installer action to execute a command line script to install MSMQ.

Here's my Installer class (your options may obviously vary):

public partial class MSMQInstaller : Installer
{
    public MSMQInstaller()
    {
        InitializeComponent();
    }

    [DllImport("kernel32")]
    static extern IntPtr LoadLibrary(string lpFileName);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool FreeLibrary(IntPtr hModule);

    public override void Install(IDictionary stateSaver)
    {
        base.Install(stateSaver);

        bool loaded;

        try
        {
            IntPtr handle = LoadLibrary("Mqrt.dll");

            if (handle == IntPtr.Zero || handle.ToInt32() == 0)
            {
                loaded = false;
            }
            else
            {
                loaded = true;

                FreeLibrary(handle);
            }
        }
        catch
        {
            loaded = false;
        }

        if (!loaded)
        {
            if (Environment.OSVersion.Version.Major < 6) // Windows XP or earlier
            {
                string fileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "MSMQAnswer.ans");

                using (System.IO.StreamWriter writer = new System.IO.StreamWriter(fileName))
                {
                    writer.WriteLine("[Version]");
                    writer.WriteLine("Signature = \"$Windows NT$\"");
                    writer.WriteLine();
                    writer.WriteLine("[Global]");
                    writer.WriteLine("FreshMode = Custom");
                    writer.WriteLine("MaintenanceMode = RemoveAll");
                    writer.WriteLine("UpgradeMode = UpgradeOnly");
                    writer.WriteLine();
                    writer.WriteLine("[Components]");
                    writer.WriteLine("msmq_Core = ON");
                    writer.WriteLine("msmq_LocalStorage = ON");
                }

                using (System.Diagnostics.Process p = new System.Diagnostics.Process())
                {
                    System.Diagnostics.ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo("sysocmgr.exe", "/i:sysoc.inf /u:\"" + fileName + "\"");

                    p.StartInfo = start;

                    p.Start();
                    p.WaitForExit();
                }
            }
            else // Vista or later
            {
                using (System.Diagnostics.Process p = new System.Diagnostics.Process())
                {
                    System.Diagnostics.ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo("ocsetup.exe", "MSMQ-Container;MSMQ-Server /passive");

                    p.StartInfo = start;

                    p.Start();
                    p.WaitForExit();
                }
            }
        }
    }
}