2

MSMQ を介して通信する 2 つのコンポーネントを持つ .NET プロジェクトがあります。Microsoft が不可解にも Visual Studio 2012 でのインストーラーのサポートを終了したため、Wix を使用してインストーラーを構築しています。Wix インストーラーで MSMQ のインスタンスを作成するプロセスには非常に満足しています。 MSMQ がコンピューターにインストールされているかどうかを検出します (Mqrt.dll の読み込みを試みることにより)。

Wix を使用して MSMQ Windows システム コンポーネント自体をインストールする方法を知っている人はいますか? Windows にシステム コンポーネントをインストールするように Wix に指示させる方法はありますか?

4

2 に答える 2

4

長い時間がかかりましたが、ついにこれを行うエレガントな方法を見つけました。

1) Visual Studio で、新しい WiX C# カスタム アクション プロジェクトを作成します。

2) 以下を CustomAction.cs ファイルに貼り付けます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Deployment.WindowsInstaller;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;

namespace InstallMsmq
{
    public class CustomActions
    {
        [CustomAction]
        public static ActionResult CustomAction1(Session session)
        {
            session.Log("Begin CustomAction1");

            return ActionResult.Success;
        }

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

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

        [CustomAction]
        public static ActionResult InstallMsmq(Session session)
        {

            ActionResult result = ActionResult.Failure;
            session.Log("Detecting MSMQ");
            bool loaded;
            CreateConfigFile();
            CreateWindows8InstallerScript();

            try
            {
                IntPtr handle = LoadLibrary("Mqrt.dll");
                if (handle == IntPtr.Zero || handle.ToInt32() == 0)
                {
                    loaded = false;
                }
                else
                {
                    loaded = true;
                    session.Log("MSMQ is already installed");
                    result = ActionResult.Success;
                    FreeLibrary(handle);
                }
            }
            catch
            {
                loaded = false;
            }

            if (!loaded)
            {
                session.Log("Installing MSMQ");
                try
                {

                    Version win8version = new Version(6, 2, 9200, 0);

                    if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version >= win8version)//Windows 8 or higher
                    {
                        // its win8 or higher.

                        session.Log("Windows 8 or Server 2012 detected");

                        using (Process p = new Process())
                        {
                            session.Log("Installing MSMQ Server");
                            ProcessStartInfo containerStart = new ProcessStartInfo("MSMQWindows8.bat");
                            containerStart.Verb = "runas";
                            p.StartInfo = containerStart;                            
                            bool success = p.Start();
                            p.WaitForExit();
                        }
                    }
                    else if (Environment.OSVersion.Version.Major < 6) // Windows XP or earlier
                    {
                        session.Log("Windows XP or earlier detected");
                        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 (Process p = new Process())
                        {
                            session.Log("Installing MSMQ Container");
                            ProcessStartInfo start = new ProcessStartInfo("sysocmgr.exe", "/i:sysoc.inf /u:\"" + fileName + "\"");
                            p.StartInfo = start;
                            p.Start();
                            p.WaitForExit();
                        }
                    }
                    else if (Environment.OSVersion.Version.Major < 8) // Vista or later
                    {
                        session.Log("Windows Vista or Windows 7 detected");
                        using (Process p = new Process())
                        {
                            session.Log("Installing MSMQ Container");
                            ProcessStartInfo containerStart = new ProcessStartInfo("ocsetup.exe", "MSMQ-Container /unattendFile:MSMQ.xml");
                            containerStart.Verb = "runas";
                            p.StartInfo = containerStart;
                            p.Start();
                            p.WaitForExit();
                        }
                        using (Process p = new Process())
                        {
                            session.Log("Installing MSMQ Server");
                            ProcessStartInfo serverStart = new ProcessStartInfo("ocsetup.exe", "MSMQ-Server /unattendFile:MSMQ.xml");
                            serverStart.Verb = "runas";
                            p.StartInfo = serverStart;
                            p.Start();
                            p.WaitForExit();
                        }
                    }
                    session.Log("Installation of MSMQ Completed succesfully");
                    result = ActionResult.Success;
                }
                catch (Exception ex)
                {
                    session.Log("Installation of MSMQ failed due to " + ex.Message);
                }
            }
            return result;
        }

        private static void CreateWindows8InstallerScript()
        {
            StreamWriter configFile = new StreamWriter("MSMQWindows8.bat");
            configFile.WriteLine("%WINDIR%\\SysNative\\dism.exe /online /enable-feature /all /featurename:MSMQ-Server");
            configFile.Close();
        }
        private static void CreateConfigFile()
        {
            StreamWriter configFile = new StreamWriter("MSMQ.xml");
            configFile.WriteLine("<?xml version=\"1.0\"?>");
            configFile.WriteLine("");
            configFile.WriteLine("<unattend>");
            configFile.WriteLine("");
            configFile.WriteLine("  <servicing>");
            configFile.WriteLine("");
            configFile.WriteLine("    <package action=\"configure\">");
            configFile.WriteLine("");
            configFile.WriteLine("<assemblyIdentity name=\"Microsoft-Windows-Foundation-Package\" version=\"6.0.6000.16386\" language=\"neutral\" processorArchitecture=\"AMD64\" publicKeyToken=\"31bf3856ad364e35\" versionScope=\"nonSxS\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("      <selection name=\"MSMQ-Container\" state=\"true\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("<selection name=\"MSMQ-Server\" state=\"true\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("<selection name=\"MSMQ-Triggers\" state=\"true\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("<selection name=\"MSMQ-DCOMProxy\" state=\"true\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("<selection name=\"MSMQ-Multicast\" state=\"true\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("<selection name=\"MSMQ-ADIntegration\" state=\"true\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("<selection name=\"MSMQ-HTTP\" state=\"true\"/>");
            configFile.WriteLine("");
            configFile.WriteLine("    </package>");
            configFile.WriteLine("");
            configFile.WriteLine("  </servicing>");
            configFile.WriteLine("");
            configFile.WriteLine("</unattend>");
            configFile.Close();
        }
    }
}

3) カスタム アクションをコンパイルする

4) 以下を WiX setup.wxs ファイルに追加します。

<Binary SourceFile="[path to custom action project]\bin\[Debug or Release]\[custom action project name].CA.dll" Id="[custom action project name]step" />
<CustomAction Id="[custom action project name]CustomAction" BinaryKey="[custom action project name]step" DllEntry="[custom action project name]" Execute="deferred" Impersonate="no"/>
<InstallExecuteSequence>
  <Custom Action="[custom action project name]CustomAction" Before="InstallFiles"/>
</InstallExecuteSequence> 

5) カスタム アクションは、インストール プロセス中の任意の時点で実行するように構成できます (詳細はこちら: http://wixtoolset.org/documentation/manual/v3/xsd/wix/installexecutesequence.html )。上記の例では、.wxs ファイルに詳述されているファイルをインストールする前に、カスタム アクションを実行します。

6) テスト - すべてがうまくいけば、インストール シーケンスの一部として msmq をインストールするセットアップ ファイルが作成されます。

于 2014-01-27T11:04:02.630 に答える
-1

製品がMSMQ、.NET Framework、SQL Serverなどの追加のサードパーティの前提条件に依存している場合は、ブートストラッププログラムを使用して一連のインストールを実行する必要があります。最初に必要な前提条件を1つずつ実行し、次にメインの前提条件を実行します。製品のインストール。

WiXでは、これらのチェーンはバンドルと呼ばれ、バーンブートストラッパーを使用して作成/実行されます。

于 2013-03-06T07:56:00.250 に答える