/// <summary> /// The main entry point for the application. /// </summary> private static void Main(String[] args) { // Trace copyright information Assembly entryAsm = Assembly.GetEntryAssembly(); // Dump some info Trace.TraceInformation("SanteDB Startup : v{0}", entryAsm.GetName().Version); Trace.TraceInformation("SanteDB Working Directory : {0}", entryAsm.Location); Trace.TraceInformation("Operating System: {0} {1}", Environment.OSVersion.Platform, Environment.OSVersion.VersionString); Trace.TraceInformation("CLI Version: {0}", Environment.Version); AppDomain.CurrentDomain.SetData( "DataDirectory", Path.GetDirectoryName(typeof(Program).Assembly.Location)); // Handle Unahndled exception AppDomain.CurrentDomain.UnhandledException += (o, e) => { Trace.TraceError("++++++ FATAL APPLICATION ERROR ++++++++\r\n{0}", e.ExceptionObject); EventLog.WriteEntry("SanteDB Host Process", $"++++++ FATAL APPLICATION ERROR ++++++++\r\n{e.ExceptionObject}", EventLogEntryType.Error, 999); Environment.Exit(999); }; // Parser ParameterParser <ConsoleParameters> parser = new ParameterParser <ConsoleParameters>(); bool hasConsole = true; try { var parameters = parser.Parse(args); var instanceSuffix = !String.IsNullOrEmpty(parameters.InstanceName) ? $"-{parameters.InstanceName}" : null; // What to do? if (parameters.ShowHelp) { parser.WriteHelp(Console.Out); } else if (parameters.InstallCerts) { Console.WriteLine("Installing security certificates..."); SecurityExtensions.InstallCertsForChain(); } else if (parameters.Install) { if (!ServiceTools.ServiceInstaller.ServiceIsInstalled($"SanteDB{instanceSuffix}")) { Console.WriteLine("Installing Service..."); if (!String.IsNullOrEmpty(instanceSuffix)) { var configFile = parameters.ConfigFile; if (String.IsNullOrEmpty(configFile)) { configFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), $"santedb.config.{parameters.InstanceName}.xml"); } else if (!Path.IsPathRooted(configFile)) { configFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), configFile); } ServiceTools.ServiceInstaller.Install($"SanteDB{instanceSuffix}", $"SanteDB Host Process - {parameters.InstanceName}", $"{Assembly.GetEntryAssembly().Location} --name={parameters.InstanceName} --config={configFile}", null, null, ServiceTools.ServiceBootFlag.AutoStart); } else { ServiceTools.ServiceInstaller.Install($"SanteDB", "SanteDB Host Process", $"{Assembly.GetEntryAssembly().Location}", null, null, ServiceTools.ServiceBootFlag.AutoStart); } } } else if (parameters.UnInstall) { if (ServiceTools.ServiceInstaller.ServiceIsInstalled($"SanteDB{instanceSuffix}")) { Console.WriteLine("Un-Installing Service..."); ServiceTools.ServiceInstaller.StopService($"SanteDB{instanceSuffix}"); ServiceTools.ServiceInstaller.Uninstall($"SanteDB{instanceSuffix}"); } } else if (parameters.GenConfig) { SanteDBConfiguration configuration = new SanteDBConfiguration(); ApplicationServiceContextConfigurationSection serverConfiguration = new ApplicationServiceContextConfigurationSection(); Console.WriteLine("Will generate full default configuration..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(typeof(Program).Assembly.Location), "*.dll")) { try { var asm = Assembly.LoadFile(file); Console.WriteLine("Adding service providers from {0}...", file); serverConfiguration.ServiceProviders.AddRange(asm.ExportedTypes.Where(t => typeof(IServiceImplementation).IsAssignableFrom(t) && !t.IsAbstract && !t.ContainsGenericParameters && t.GetCustomAttribute <ServiceProviderAttribute>() != null).Select(o => new TypeReferenceConfiguration(o))); Console.WriteLine("Adding sections from {0}...", file); configuration.Sections.AddRange(asm.ExportedTypes.Where(t => typeof(IConfigurationSection).IsAssignableFrom(t)).Select(t => CreateFullXmlObject(t))); } catch (Exception e) { Console.WriteLine("Skipping {0} due to {1}", file, e.Message); } } configuration.RemoveSection <ApplicationServiceContextConfigurationSection>(); serverConfiguration.ThreadPoolSize = Environment.ProcessorCount * 16; configuration.AddSection(serverConfiguration); using (var fs = File.Create(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "default.config.xml"))) configuration.Save(fs); } else if (parameters.ConsoleMode) { Console.WriteLine("SanteDB (SanteDB) {0} ({1})", entryAsm.GetName().Version, entryAsm.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion); Console.WriteLine("{0}", entryAsm.GetCustomAttribute <AssemblyCopyrightAttribute>().Copyright); Console.WriteLine("Complete Copyright information available at http://SanteDB.codeplex.com/wikipage?title=Contributions"); ServiceUtil.Start(typeof(Program).GUID, new FileConfigurationService(parameters.ConfigFile)); if (!parameters.StartupTest) { // Did the service start properly? if (!ApplicationServiceContext.Current.IsRunning) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Application context did not start properly and is in maintenance mode..."); Console.ResetColor(); } if (Environment.OSVersion.Platform == PlatformID.Win32NT) { ManualResetEvent quitEvent = new ManualResetEvent(false); Console.CancelKeyPress += (o, e) => { Console.WriteLine("Service shutting down..."); ServiceUtil.Stop(); quitEvent.Set(); }; Console.WriteLine("Service started (CTRL+C to stop)..."); quitEvent.WaitOne(); } else { // Now wait until the service is exiting va SIGTERM or SIGSTOP UnixSignal[] signals = new UnixSignal[] { new UnixSignal(Mono.Unix.Native.Signum.SIGINT), new UnixSignal(Mono.Unix.Native.Signum.SIGTERM), new UnixSignal(Mono.Unix.Native.Signum.SIGQUIT), new UnixSignal(Mono.Unix.Native.Signum.SIGHUP) }; int signal = UnixSignal.WaitAny(signals); // Gracefully shutdown ServiceUtil.Stop(); try // remove the lock file { File.Delete("/tmp/SanteDB.exe.lock"); } catch { } } } } else { hasConsole = false; ServiceBase[] servicesToRun = new ServiceBase[] { new SanteDBService() }; ServiceBase.Run(servicesToRun); } } catch (Exception e) { #if DEBUG Trace.TraceError("011 899 981 199 911 9725 3!!! {0}", e.ToString()); EventLog.WriteEntry("SanteDB Host Process", $"011 899 981 199 911 9725 3!!! {e}", EventLogEntryType.Error, 911); #else Trace.TraceError("Error encountered: {0}. Will terminate", e); #endif if (hasConsole) { Console.WriteLine("011 899 981 199 911 9725 3!!! {0}", e.ToString()); } try { EventLog.WriteEntry("SanteDB Host Process", $"011 899 981 199 911 9725 3!!! {e}", EventLogEntryType.Error, 911); } catch (Exception e1) { Trace.TraceWarning("Could not emit the error to the EventLog - {0}", e1); } Environment.Exit(911); } }
/// <summary> /// The main entry point for the application. /// </summary> static void Main(String[] args) { // Trace copyright information Assembly entryAsm = Assembly.GetEntryAssembly(); // Dump some info Trace.TraceInformation("SanteDB Startup : v{0}", entryAsm.GetName().Version); Trace.TraceInformation("SanteDB Working Directory : {0}", entryAsm.Location); Trace.TraceInformation("Operating System: {0} {1}", Environment.OSVersion.Platform, Environment.OSVersion.VersionString); Trace.TraceInformation("CLI Version: {0}", Environment.Version); AppDomain.CurrentDomain.SetData( "DataDirectory", Path.GetDirectoryName(typeof(Program).Assembly.Location)); // Handle Unahndled exception AppDomain.CurrentDomain.UnhandledException += (o, e) => { Trace.TraceError("++++++ FATAL APPLICATION ERROR ++++++++\r\n{0}", e.ExceptionObject); EventLog.WriteEntry("SanteDB Host Process", $"++++++ FATAL APPLICATION ERROR ++++++++\r\n{e.ExceptionObject}", EventLogEntryType.Error, 999); Environment.Exit(999); }; // Parser ParameterParser <ConsoleParameters> parser = new ParameterParser <ConsoleParameters>(); bool hasConsole = true; try { var parameters = parser.Parse(args); EntitySource.Current = new EntitySource(new PersistenceEntitySource()); // What to do? if (parameters.ShowHelp) { parser.WriteHelp(Console.Out); } else if (parameters.Install) { if (!ServiceTools.ServiceInstaller.ServiceIsInstalled("SanteDB")) { Console.WriteLine("Installing Service..."); ServiceTools.ServiceInstaller.Install("SanteDB", "SanteDB Host Process", Assembly.GetEntryAssembly().Location, null, null, ServiceTools.ServiceBootFlag.AutoStart); } } else if (parameters.UnInstall) { if (ServiceTools.ServiceInstaller.ServiceIsInstalled("SanteDB")) { Console.WriteLine("Un-Installing Service..."); ServiceTools.ServiceInstaller.StopService("SanteDB"); ServiceTools.ServiceInstaller.Uninstall("SanteDB"); } } else if (parameters.GenConfig) { SanteDBConfiguration configuration = new SanteDBConfiguration(); ApplicationServiceContextConfigurationSection serverConfiguration = new ApplicationServiceContextConfigurationSection(); Console.WriteLine("Will generate full default configuration..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(typeof(Program).Assembly.Location), "*.dll")) { try { var asm = Assembly.LoadFile(file); Console.WriteLine("Adding service providers from {0}...", file); serverConfiguration.ServiceProviders.AddRange(asm.ExportedTypes.Where(t => typeof(IServiceImplementation).IsAssignableFrom(t) && !t.IsAbstract && !t.ContainsGenericParameters && t.GetCustomAttribute <ServiceProviderAttribute>() != null).Select(o => new TypeReferenceConfiguration(o))); Console.WriteLine("Adding sections from {0}...", file); configuration.Sections.AddRange(asm.ExportedTypes.Where(t => typeof(IConfigurationSection).IsAssignableFrom(t)).Select(t => CreateFullXmlObject(t))); } catch (Exception e) { Console.WriteLine("Skipping {0} due to {1}", file, e.Message); } } configuration.RemoveSection <ApplicationServiceContextConfigurationSection>(); serverConfiguration.ThreadPoolSize = Environment.ProcessorCount; configuration.AddSection(serverConfiguration); using (var fs = File.Create(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "default.config.xml"))) configuration.Save(fs); } else if (parameters.ConsoleMode) { Console.WriteLine("SanteDB (SanteDB) {0} ({1})", entryAsm.GetName().Version, entryAsm.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion); Console.WriteLine("{0}", entryAsm.GetCustomAttribute <AssemblyCopyrightAttribute>().Copyright); Console.WriteLine("Complete Copyright information available at http://SanteDB.codeplex.com/wikipage?title=Contributions"); ServiceUtil.Start(typeof(Program).GUID); if (!parameters.StartupTest) { // Did the service start properly? if (!ApplicationContext.Current.IsRunning) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Application context did not start properly and is in maintenance mode..."); Console.ResetColor(); } ManualResetEvent quitEvent = new ManualResetEvent(false); Console.CancelKeyPress += (o, e) => { Console.WriteLine("Service shutting down..."); ServiceUtil.Stop(); quitEvent.Set(); }; Console.WriteLine("Service started (CTRL+C to stop)..."); quitEvent.WaitOne(); } } else { hasConsole = false; ServiceBase[] servicesToRun = new ServiceBase[] { new SanteDB() }; ServiceBase.Run(servicesToRun); } } catch (Exception e) { #if DEBUG Trace.TraceError("011 899 981 199 911 9725 3!!! {0}", e.ToString()); if (hasConsole) { Console.WriteLine("011 899 981 199 911 9725 3!!! {0}", e.ToString()); } EventLog.WriteEntry("SanteDB Host Process", $"011 899 981 199 911 9725 3!!! {e}", EventLogEntryType.Error, 911); #else Trace.TraceError("Error encountered: {0}. Will terminate", e.Message); #endif Environment.Exit(911); } }
/// <summary> /// When implemented in a derived class, executes when a Stop command is sent to the service by the Service Control Manager (SCM). Specifies actions to take when a service stops running. /// </summary> protected override void OnStop() { ServiceUtil.Stop(); }