Instalación de un servicio de Windows programáticamente
-
27-10-2019 - |
Pregunta
Estoy intentando instalar un servicio programáticamente a través de C#, pero me he encontrado con un problema que no puedo entender.
Después de leer un montón de documentación, estoy en ese punto en el que creo que Microsoft tiene un error (pero todos sabemos que ese no es el caso).
Así que aquí está el Main
de mi aplicación.
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
if (System.Environment.UserInteractive)
{
string parameter = string.Concat(args);
switch (parameter)
{
case "/install":
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
Console.Read();
break;
case "/uninstall":
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
break;
}
}
else
{
ServiceBase.Run(new ProxyMonitor());
}
}
Cuando se ejecuta dentro de CMD bajo privilegios de administración como SO ProxyMonitor /install
El paso en la línea se reduce a la línea:
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
Como se esperaba, y luego salta a mi clase de instalación como así:
namespace Serco.Services.ProxyMonitor
{
[RunInstaller(true)]
public class ManagedInstallation : ServiceInstaller
{
public ManagedInstallation()
{
var ProcessInstaller = new ServiceProcessInstaller();
var ServiceInstaller = new ServiceInstaller();
//set the information and privileges
ProcessInstaller.Account = ServiceConfiguration.AccountType;
ServiceInstaller.DisplayName = ServiceConfiguration.DisplayName;
ServiceInstaller.StartType = ServiceConfiguration.StartType;
ServiceInstaller.Description = ServiceConfiguration.Description;
ServiceInstaller.ServiceName = ServiceConfiguration.ServiceName;
Installers.Add(ProcessInstaller);
Installers.Add(ServiceInstaller);
}
}
}
Después de verificar el archivo de depuración, obtengo lo siguiente:
Installing assembly 'C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.InstallLog
assemblypath = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe
Installing service ...
Creating EventLog source in log Application...
Rolling back assembly 'C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.InstallLog
assemblypath = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe
Restoring event log to previous state for source .
También obtengo la excepción lanzada dentro de la siguiente llamada:
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
Declarando:
La instalación falló y se ha realizado la reversión. Debe especificar el valor para la fuente.
Actualizaciones:
Clase de configuración
namespace Serco.Services.ProxyMonitor
{
class ServiceConfiguration
{
public static string DisplayName
{
get { return "Serco Proxy Monitor"; }
}
public static string ServiceName
{
get { return "Serco Proxy Monitor"; }
}
public static string Description
{
get
{
return "Serco ProxyMonitor is a helper developed to manage the state of the proxy for the employess whilst of the internal network.";
}
}
public static ServiceStartMode StartType
{
get{return ServiceStartMode.Automatic;}
}
public static ServiceAccount AccountType
{
get{return ServiceAccount.LocalSystem;}
}
/*.. /Snip/ ..*/
}
}
Solución
Parece que la fuente de registro es nula; estás seguro que ServiceConfiguration.ServiceName
¿Está definido y tiene un valor?
Otros consejos
Lo descubrí y pensé que publicaría encasar que otros pudieran tener el mismo problema.
Fue una combinación de algunas cosas, pero simplemente las mostraré rápidamente:
public static string ServiceName
{
get { return "Serco Proxy Monitor"; }
}
- Tuvo que convertirse
return "SercoProxyMonitor";
Debido a los espacios - Retiró el
UnhandledException
que luego mostró más rastros de pila - Necesitaba tener los derechos completos del administrador.
Creo que el problema principal fue que el ServiceInstaller
estaba usando el ServiceName
para crear y EventLogSource
, Y como había espacios dentro del EventLogSource
Estaba lanzando un ajuste.