Example #1
0
 /// <summary>
 /// Takes over where <see cref="WindowsService{ServiceType}(WindowsServiceInitOptions)"/> left off.
 /// </summary>
 /// <typeparam name="ServiceType"></typeparam>
 /// <param name="myService"></param>
 /// <param name="options"></param>
 /// <param name="settingsObj"></param>
 private static void LinuxWindowsService <ServiceType>(ServiceType myService, WindowsServiceInitOptions options, SerializableObjectBase settingsObj) where ServiceType : ServiceBase, new()
 {
     string[] args = Environment.GetCommandLineArgs();
     if (args.Length == 1)
     {
         Console.WriteLine(myService.ServiceName + " " + Globals.AssemblyVersion);
         Console.WriteLine("To run as a Windows Service: " + args[0] + " run");
         Console.WriteLine("To run as a command line app: " + args[0] + " cmd");
         if (settingsObj != null)
         {
             Console.WriteLine("To update the settings file: " + args[0] + " savesettings");
         }
         Console.WriteLine("Data directory: " + Globals.WritableDirectoryBase);
     }
     else if (args.Length > 1 && args[1] == "run")
     {
         ServiceBase.Run(myService);
     }
     else if (args.Length > 1 && args[1] == "cmd")
     {
         PrivateAccessor.CallMethod <ServiceType>(myService, "OnStart", new object[] { new string[0] });
         try
         {
             do
             {
                 Console.WriteLine("Running " + myService.ServiceName + " " + Globals.AssemblyVersion + " in command-line mode. Type \"exit\" to close.");
             }while (Console.ReadLine() != "exit");
         }
         finally
         {
             PrivateAccessor.CallMethod <ServiceType>(myService, "OnStop");
         }
     }
     else if (args.Length > 1 && args[1] == "savesettings")
     {
         if (settingsObj != null)
         {
             settingsObj.Save();
             Console.WriteLine("Saved settings file in " + Globals.WritableDirectoryBase);
         }
         else
         {
             Console.WriteLine("This program was not configured to use a standard settings file.");
         }
     }
 }
Example #2
0
        /// <summary>
        /// <para>Call this from your Main() function, and it takes care of all initialization for a Windows Service app with the following features:</para>
        /// <list type="bullet">
        /// <item>Logs separated by month in <see cref="Globals.WritableDirectoryBase"/> + "Logs/"</item>
        /// <item><see cref="Environment.CurrentDirectory"/> set to <see cref="Globals.WritableDirectoryBase"/></item>
        /// <item>Unhandled exceptions logged.</item>
        /// <item>(Windows Only) Service Manager GUI with "Open Data Folder" button which opens <see cref="Globals.WritableDirectoryBase"/> in Explorer.</item>
        /// <item>(Windows Only) A temporary instance of the service is automatically started if the debugger is attached.</item>
        /// <item>If the service has a public static field named "settings" which inherits from SerializableObjectBase, that field will be instantiated if necessary, loaded, then saved if the settings file does not exist.</item>
        /// </list>
        /// <para>Notice that some assumptions are made about the architecture of the application.</para>
        /// <para>When running on linux, this class simply starts the service.</para>
        /// <para>You may initialize <see cref="Globals"/> with custom values, if desired, before calling this method.</para>
        /// </summary>
        /// <typeparam name="ServiceType">Type of Service class.</typeparam>
        /// <param name="options">Optional options for service initialization.</param>
        public static void WindowsService <ServiceType>(WindowsServiceInitOptions options = null) where ServiceType : ServiceBase, new()
        {
            if (options == null)
            {
                options = new WindowsServiceInitOptions();
            }
            Directory.CreateDirectory(Globals.WritableDirectoryBase);
            Directory.CreateDirectory(Globals.WritableDirectoryBase + "Logs/");
            Globals.OverrideErrorFilePath(() => Globals.WritableDirectoryBase + "Logs/" + Globals.AssemblyName + "_" + DateTime.Now.Year + "_" + DateTime.Now.Month.ToString().PadLeft(2, '0') + ".txt");
            Environment.CurrentDirectory = Globals.WritableDirectoryBase;

            Logger.CatchAll();
            SimpleHttpLogger.RegisterLogger(Logger.httpLogger, false);

            ServiceType myService = new ServiceType();

            // Initialize the settings object, if the service has a public static field named "settings" that inherits from SerializableObjectBase.
            FieldInfo settingsField            = myService.GetType().GetField("settings", BindingFlags.Static | BindingFlags.Public);
            SerializableObjectBase settingsObj = null;

            if (settingsField != null && settingsField.FieldType.IsSubclassOf(typeof(SerializableObjectBase)))
            {
                settingsObj = (SerializableObjectBase)settingsField.GetValue(null);
                if (settingsObj == null)
                {
                    settingsObj = (SerializableObjectBase)Activator.CreateInstance(settingsField.FieldType);
                    settingsField.SetValue(null, settingsObj);
                }
                settingsObj.Load();
                settingsObj.SaveIfNoExist();
            }

            if (Platform.IsUnix() || Platform.IsRunningOnMono())
            {
                LinuxWindowsService(myService, options, settingsObj);
                return;
            }
            string serviceName = !string.IsNullOrWhiteSpace(options.ServiceName) ? options.ServiceName : myService.ServiceName;

            if (Environment.UserInteractive)
            {
                string Title = serviceName + " " + Globals.AssemblyVersion + " Service Manager";

                List <ButtonDefinition> additionalButtons = new List <ButtonDefinition>();
                if (options.ServiceManagerButtons_OpenDataFolder)
                {
                    additionalButtons.Add(new ButtonDefinition("Open Data Folder", btnOpenDataFolder_Click));
                }
                if (options.ServiceManagerButtons_UpdateSettingsFile && settingsObj != null)
                {
                    additionalButtons.Add(new ButtonDefinition("Update Settings File", (sender, ignored) =>
                    {
                        settingsObj.Save();
                        Process.Start(settingsObj.GetType().Name + ".cfg");
                    }));
                }
                if (options.ServiceManagerButtons != null)
                {
                    foreach (ButtonDefinition btn in options.ServiceManagerButtons)
                    {
                        additionalButtons.Add(btn);
                    }
                }

                bool didStart = false;
                if (Debugger.IsAttached || options.RunForDebugging)
                {
                    PrivateAccessor.CallMethod <ServiceType>(myService, "OnStart", new object[] { new string[0] });
                    didStart = true;
                }

                try
                {
                    System.Windows.Forms.Application.Run(new ServiceManager(Title, serviceName, additionalButtons.ToArray()));
                }
                finally
                {
                    if (didStart)
                    {
                        PrivateAccessor.CallMethod <ServiceType>(myService, "OnStop");
                    }
                }
            }
            else
            {
                ServiceBase.Run(myService);
            }
        }