Ich arbeite an einer Anwendung, die MSMQ für Interprozesskommunikation verwendet, und ich brauche das Setup-Projekt, um den Dienst zu installieren, wenn es nicht bereits vorhanden ist. Ich habe nach Informationen gesucht, um es zu einer Voraussetzung zu machen, aber bisher war es mir nicht gelungen, das zu finden. Irgendwelche Ideen?Einschließlich MSMQ als Voraussetzung für meine Anwendung
Antwort
Entdeckt die Antwort auf eigene Faust ... der Windows-Komponente Installer ist nicht durch die typische Unfähigkeit zu mehr als einer MSI zu jeder Zeit zu verkrüppeln, so kann ich eine benutzerdefinierte Installer-Aktion, um einen Befehl auszuführen verwenden Zeilenskript zur Installation von MSMQ.
Hier ist meine Installer-Klasse (Ihre Optionen offensichtlich variieren kann):
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();
}
}
}
}
}
Danke !! Hier ist die VB.Net-Version für alle Interessierten.
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
Was ist mit dem Befehl pkgmgr?
pkgmgr/iu: MSMQ-Container; MSMQ-Server
Das scheint das gleiche zu tun wie "ocsetup.exe" in meiner Antwort. –
Aber ocsetup in nicht standardmäßig bei Windows 8.1 vorhanden – Miguel
Das ist ein Cracker. Ich danke Ihnen für das Teilen. –
Wie rufen Sie die Installationsmethode auf? Ich habe bereits den Verweis 'system.configuration.Install' hinzugefügt. Die InitializeComponent-Methode ist eine Methode in der Basis? Wie kann ich diese Klasse verwenden, um MSMQ zu installieren? –
@Adam: Haben Sie eine separate Klassenbibliothek für diese Installer-Klasse erstellt? Ich erhalte den Fehler "InitializeComponent kann nicht gefunden werden", wenn ich Ihren Code verwende. – Abhishek