代码之家  ›  专栏  ›  技术社区  ›  Adam Robinson

将MSMQ作为我申请的先决条件

  •  21
  • Adam Robinson  · 技术社区  · 16 年前

    我正在开发一个使用MSMQ进行进程间通信的应用程序,如果尚未安装该服务,我需要安装项目来安装该服务。我已经四处查看了关于将其作为先决条件的信息,但到目前为止,我没有找到这个。有什么想法吗?

    3 回复  |  直到 16 年前
        1
  •  26
  •   Adam Robinson    15 年前

    我自己发现了答案…windows组件安装程序不会因为无法在任何给定时间安装多个MSI而受损,因此我可以使用自定义安装程序操作执行命令行脚本来安装MSMQ。

    这是我的安装程序类(您的选项可能明显不同):

    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();
                    }
                }
            }
        }
    }
    
        2
  •  5
  •   Scott Gowell    15 年前

    那么pkgmgr命令呢?

    pkgmgr/iu:MSMQ容器;MSMQ服务器

        3
  •  3
  •   Mona    15 年前

    非常感谢。这是VB.Net版本,供感兴趣的人使用。

    Option Explicit On
    Option Strict On
    
    Imports System.Diagnostics.Process
    Imports System.IO
    Imports System.Text
    'Required in all cases when calling API functions
    Imports System.Runtime.InteropServices
    Imports System.Configuration.Install.Installer
    
    <System.ComponentModel.RunInstallerAttribute(True)> _
    Public Class msmqInstaller
        Inherits System.Configuration.Install.Installer
    
        Private Declare Function LoadLibrary Lib "kernel32" (ByVal lpFileName As String) As IntPtr`enter code here`
        <DllImport("KERNEL32.DLL", EntryPoint:="FreeLibrary", SetLastError:=True)> _
         Public Shared Function FreeLibrary(ByVal hModule As IntPtr) As Boolean
            ' Leave function empty - DLLImport attribute 
            ' forces calls to LoadLibrary to
            ' be forwarded to LoadLibrary in KERNEL32.DLL
        End Function
    
        Public Const MAX_PATH As Integer = 256
        ' Dim testKernel As loadlibrary
        Dim p As New Process
        '  Dim startInfo As New ProcessStartInfo("sysocmgr.exe", "/i:sysoc.inf /u:\"" + fileName + " \ "")
        Dim fileName As String = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "MSMQAnswer.ans")
        Dim writer As New StreamWriter(fileName)
    
        ' Override the 'Install' method of the Installer class. When overridden in a derived class, performs the installation.
        'You must override the Install and Uninstall methods to add the code to perform your custom installation steps.
        Public Overrides Sub Install(ByVal mySavedState As IDictionary)
            MyBase.Install(mySavedState)
            Dim loaded As Boolean = False
            Dim fileName As String
            Dim writer As StreamWriter
            Dim p As Process
    
            Try
                Dim handle As IntPtr = LoadLibrary("Mqrt.dll")
                If handle = IntPtr.Zero Or handle.ToInt32 = 0 Then
                    loaded = False
                Else
                    loaded = True
                    FreeLibrary(handle)
                End If
            Catch ex As Exception
                loaded = False
            End Try
    
            If Not loaded = True Then
                If Environment.OSVersion.Version.Major < 6 Then ' windows xp or earlier
                    fileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "MSMQAnswer.ans")
                    writer = New System.IO.StreamWriter(fileName)
                    Using writer
                        writer.WriteLine("[Version]")
                        '  writer.WriteLine("Signature = \"$Windows NT$\"")
                        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")
                    End Using
                    p = New System.Diagnostics.Process()
                    Using p
                        Dim startInfo As New ProcessStartInfo("sysocmgr.exe", "/i:sysoc.inf /u:\" + fileName + " \ ")
                        p.StartInfo = startInfo
                        p.Start()
                        p.WaitForExit()
                    End Using
                Else 'windows vista or later, server 03 
                    p = New System.Diagnostics.Process
                    Using p
                        Dim startInfo As New ProcessStartInfo("ocsetup.exe", "MSMQ-Container;MSMQ-Server /passive")
                        p.StartInfo = startInfo
                        p.Start()
                        p.WaitForExit()
                    End Using
                End If
            End If
    
    
    
        End Sub
    
    End Class