Estoy trabajando en una aplicación que usa MSMQ para la comunicación entre procesos, y necesito el proyecto de instalación para poder instalar el servicio si aún no lo está. He revisado la información para que sea un requisito previo, pero hasta ahora no he tenido éxito en encontrar esto. ¿Algunas ideas?Incluyendo MSMQ como prerrequisito para mi aplicación
Respuesta
Descubrí la respuesta por mi cuenta ... el instalador de componentes de Windows no se ve obstaculizado por la incapacidad típica de instalar más de un MSI en un momento dado, así que puedo usar una acción de instalador personalizada para ejecutar un comando secuencia de comandos de línea para instalar MSMQ.
Aquí es mi clase de instalación (las opciones pueden variar obviamente):
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();
}
}
}
}
}
gracias !! Aquí está la versión de VB.Net para cualquiera que esté interesado.
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
¿Qué pasa con el comando pkgmgr?
pkgmgr/iu: MSMQ-Container; MSMQ-Servidor
Parece que está haciendo lo mismo que 'ocsetup.exe' en mi respuesta. –
Pero ocsetup en no presente por defecto en Windows 8.1 – Miguel
- 1. SQL CE 4.0 como InstallShield Prerrequisito
- 2. encadenado msi/Bootstrapper/prerrequisito?
- 3. Mylyn como aplicación para mi escritorio
- 4. cola de mensajes para iOS/iPad, algo así como MSMQ?
- 5. MSMQ para persistencia?
- 6. El mínimo necesario para escribir una aplicación de muestra MSMQ
- 7. usando Dropbox como servidor para mi aplicación django
- 8. Incluyendo IIS dentro de una aplicación
- 9. Como llegar CLLocationManager en mi aplicación
- 10. android: cómo registrar mi aplicación como "aplicación de cámara"
- 11. a MSMQ o no a MSMQ? (o SQL Table como la cola)
- 12. incluyendo clase como miembro en struct
- 13. Uso de msmq para el registro asincrónico
- 14. Intercambio de MSMQ para RabbitMQ en NServiceBus
- 15. MSMQ uno (cola) para muchos (oyentes) escenario
- 16. ¿Qué es Microsoft Message Queuing (MSMQ)? ¿Como funciona?
- 17. Escalabilidad MSMQ
- 18. Privado o público MSMQ
- 19. Servicio Msmq y WCF
- 20. Implementación de ClickOnce con prerrequisito de Crystal Reports
- 21. Java y MSMQ
- 22. Beneficios clave de MSMQ
- 23. Incluyendo ~/opt/lib librerías en una aplicación de Pasajeros Rails
- 24. Multidifusión, Mensajes, ActiveMQ vs. MSMQ?
- 25. Incluyendo archivos xml al implementar la aplicación WPF
- 26. android: ¿cómo puedo marcar mi aplicación como depurable?
- 27. ¿Es seguro MSMQ thread?
- 28. API especial para iniciar una aplicación desde mi aplicación
- 29. ventana emergente estilo tostada para mi aplicación
- 30. ¿Cómo puedo proteger mi aplicación iOS contra herramientas como iFunbox
Eso es una galleta. Gracias por compartir. –
¿Cómo se llama al método de instalación? Ya agregué la referencia 'system.configuration.Install' El método InitializeComponent es un método en la base? ¿Cómo puedo usar esta clase para instalar msmq? –
@ Adam: ¿Has tomado una biblioteca de clases separada para esta clase de instalador? Recibo el error "No puedo encontrar InitializeComponent" cuando uso su código. – Abhishek