2009-03-25 40 views
21

Tôi đang làm việc trên một ứng dụng sử dụng MSMQ cho liên lạc liên tiến trình và tôi cần dự án thiết lập để có thể cài đặt dịch vụ nếu chưa có. Tôi đã kiểm tra xung quanh để biết thông tin về làm cho nó là một điều kiện tiên quyết, nhưng cho đến nay tôi đã không thành công trong việc tìm kiếm này. Ý tưởng nào?Bao gồm MSMQ làm điều kiện tiên quyết cho đơn đăng ký của tôi

Trả lời

26

Phát hiện câu trả lời của riêng mình ... trình cài đặt thành phần không bị tê liệt do không có khả năng cài đặt nhiều hơn một MSI vào bất kỳ thời điểm nào, vì vậy tôi có thể sử dụng hành động cài đặt tùy chỉnh để thực thi lệnh dòng lệnh để cài đặt MSMQ.

Đây là lớp Installer của tôi (tùy chọn của bạn rõ ràng là có thể thay đổi):

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(); 
       } 
      } 
     } 
    } 
} 
+0

Đó là bánh quy giòn. Cảm ơn bạn đã chia sẻ. –

+0

Làm thế nào để bạn gọi phương thức cài đặt? Tôi đã thêm tham chiếu 'system.configuration.Install' Phương thức InitializeComponent là một phương thức trong cơ sở? làm thế nào tôi có thể sử dụng lớp này để cài đặt msmq? –

+0

@Adam: Bạn đã lấy một thư viện lớp riêng cho lớp trình cài đặt này chưa? Tôi gặp lỗi "Không thể tìm thấy InitializeComponent" khi tôi sử dụng mã của bạn. – Abhishek

3

cảm ơn !! Đây là phiên bản VB.Net cho bất kỳ ai quan tâm.

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 
5

Còn lệnh pkgmgr thì sao?

pkgmgr/iu: MSMQ-Container; MSMQ-Server

+0

Điều đó dường như đang làm điều tương tự như 'ocsetup.exe' trong câu trả lời của tôi. –

+4

Nhưng ocsetup không hiện diện theo mặc định tại Windows 8.1 – Miguel

Các vấn đề liên quan