Answered Need to run a console application as a service

Deepak

New member
Joined
Feb 12, 2021
Messages
3
Programming Experience
1-3
I have a console application which runs as a scheduler every 15 minutes. This needs to be active at all times. But my VM is being rebooted hence, the application closes sometimes.

Right now, I copy my code into VM and run the Release mode of the application. Can this be converted to a windows service so that the application starts by itself even if the VM reboots at any time. Please help me with the steps.

Thanks
 
Solution
In my opinion, the best way to go is to create a project that can be run as a Console application or as a Windows service. The good thing about that is that it makes debugging the application much easier, because debugging a Windows service is a right pain. Here are the important bits of an application that I created that is currently running in production with the NSW state government. Note that the project was created as a Console Application.
Program.cs:
using System.IO;
using System.Linq;
using System.ServiceProcess;
using SI.Moh.Phisco_Periph.Dto.Mapping;

namespace SI.Moh.Periph.Submissions.Service
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>...

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,917
Location
Sydney, Australia
Programming Experience
10+
In my opinion, the best way to go is to create a project that can be run as a Console application or as a Windows service. The good thing about that is that it makes debugging the application much easier, because debugging a Windows service is a right pain. Here are the important bits of an application that I created that is currently running in production with the NSW state government. Note that the project was created as a Console Application.
Program.cs:
using System.IO;
using System.Linq;
using System.ServiceProcess;
using SI.Moh.Phisco_Periph.Dto.Mapping;

namespace SI.Moh.Periph.Submissions.Service
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            DomainMapper.MapDomain();

            if (args.Length == 1 && args[0] == "/console")
            {
                // Run the application as a Console app.
                using (var processor = new SubmissionProcessor())
                {
                    var folder = new DirectoryInfo(Properties.Settings.Default.SubmissionsRootFolder);

                    foreach (var file in folder.GetFiles(Properties.Settings.Default.SubmissionFileNamePattern).OrderBy(fi => fi.CreationTime))
                    {
                        processor.EnqueueFile(file.FullName);
                    }

                    processor.ProcessQueuedFiles();
                }
            }
            else
            {
                // Run the application as a Windows service.
                var servicesToRun = new ServiceBase[]
                {
                    new SubmissionService()
                };

                ServiceBase.Run(servicesToRun);
            }
        }
    }
}
If the argument /console is received on the commandline, the application will run as a regular Console app. I have that argument set on the Debug page of the project properties. Otherwise, the application assumes that it is installed as a Windows service.
SubmissionService:
using System;
using System.IO;
using System.ServiceProcess;
using ApplicationLogger = SI.Moh.Phisco_Periph.Global.ApplicationLogger;

namespace SI.Moh.Periph.Submissions.Service
{
    public partial class SubmissionService : ServiceBase
    {
        private const string ERROR_LOG_NAME = "PeriphErrorLog";
        private const string INFO_LOG_NAME = "PeriphInfoLog";

        private SubmissionProcessor processor;

        public SubmissionService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            try
            {
                processor = new SubmissionProcessor();

                var path = Properties.Settings.Default.SubmissionsRootFolder;
                var filter = Properties.Settings.Default.SubmissionFileNamePattern;

#if DEBUG
                ApplicationLogger.Inst.LogInfo(INFO_LOG_NAME, "Path: " + path);
                ApplicationLogger.Inst.LogInfo(INFO_LOG_NAME, "Filter: " + filter);
#endif

                // Process files already in the submission folder.
                foreach (var file in new DirectoryInfo(path).GetFiles(filter))
                {
                    processor.EnqueueFile(file.FullName);
                }

                processor.ProcessQueuedFilesAsync();

                // Watch for new files in the submission folder.
                submissionFolderWatcher.Path = path;
                submissionFolderWatcher.Filter = filter;
                submissionFolderWatcher.EnableRaisingEvents = true;
            }
            catch (Exception ex)
            {
                ApplicationLogger.Inst.LogException(ERROR_LOG_NAME, ex.Message, ex);
            }
        }

        protected override void OnStop()
        {
        }

        private void submissionFolderWatcher_Renamed(object sender, RenamedEventArgs e)
        {
            ApplicationLogger.Inst.LogInfo(INFO_LOG_NAME, "File detected: " + e.FullPath);

            processor.EnqueueFile(e.FullPath);
            processor.ProcessQueuedFilesAsync();
        }
    }
}
As you can see, the if block in the Main method loops through the files in a folder and adds them to a queue, then calls SubmissionProcessor.ProcessQueuedFiles. The else block creates a SubmissionService object and that does the same thing in its OnStart method, so when the application starts up as a Windows service, and also in the Renamed event handler of a FileSystemWatcher.
runasconsole.bat:
REM =----------------------------------------------------------=
REM Runs the PeriPH Submission Processor Service as a console app.
REM Please ensure you run this batch file as Administrator,
REM and that the PeriPH Submission Processor Service is NOT running.
REM =----------------------------------------------------------=
REM
C:
CD bin\Debug
SI.Moh.Periph.Submissions.Service.exe /console
PAUSE
install.bat:
REM =----------------------------------------------------------=
REM Installs the PeriPH Submission Processor Service.
REM Please ensure you run this batch file as Administrator.
REM =----------------------------------------------------------=
REM
C:
CD C:\PeriPH\Service
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe" SI.Moh.Periph.Submissions.Service.exe
PAUSE
unistall.bat:
REM =----------------------------------------------------------=
REM Uninstalls the PeriPH Submission Processor Service.
REM Please ensure you run this batch file as Administrator.
REM =----------------------------------------------------------=
REM
C:
CD C:\PeriPH\Service
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe" /u SI.Moh.Periph.Submissions.Service.exe
PAUSE
 
Solution
Top Bottom