Create a Topshell-based application daemon (service) in C#/.NET application development

Time:2019-5-23

This article was first published in: Codefriend.comA programming enthusiast community focused on. NET/. NET Core development.

Article directory

C#/.NET Creates a series of articles directory for Windows services based on Topshell:

  1. C#/.NET Creates the installation and uninstallation of Windows service programs and services based on Topshell (1)
  2. Create a Topshell-based application daemon (service) in C#/.NET application development (2)
  3. Analysis and Solution of the Problem that C#/.NET Creates a Daemon of Windows Services Based on Topshell as a Client Desktop Program Started by Services does not Display UI Interface (3)

Preface

In the previous article, “Installation and Unloading of Creating Windows Service Programs and Services Based on Topshelf in C#/.NET”, we learned about the general process of creating Topshelf-based Windows Service Programs by sending C#/.NET, the configuration of parameters and the installation and unloading of services. At the same time, we demonstrated the implementation of Topshell service using a simple timed task.

Today I will continue to share technical articles on Topshell. This article mainly demonstrates how to create a Topshell-based application daemon (service) in C#/.NET application development.

Create a demo application

First, open the [TopshelfDemoService. sln] solution we created earlier. Create a new name in this solutionTopshelfDemo.ClientClient console application, which we need to guard with [Topshell of DemoService]. It’s just for demonstration, so the client has no meaningful logic and functions.Program.csIn the file, add the following sample code:

using System;

namespace TopshelfDemo.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            Console. WriteLine ("This is an ERP system sample program created by CodeFriend Network, which is currently running...");
            Console. WriteLine ("Technical Support: Codefriend Network (https://codedefautl.com) by Rector");
            Console.ReadLine();
        }
    }
}

That’s it.

Once you’ve written it, generate or run the project. You will see a console application interface, such as:

Create a Topshell-based application daemon (service) in C#/.NET application development

Implementing daemon functions

Back in the project [Topshell of DemoService], open the class fileHealthMonitorService.csThe timer function demonstrates a task to check the health of a system. Now we change the timer function to guard one or some applications.

For the convenience of demonstration, there is no re-creation of service classes. In the actual project, you can also create different service classes according to your own situation.

Modify the code as follows:

using System;
using System.Collections.Generic;
using System.Timers;

namespace TopshelfDemoService
{
    internal class HealthMonitorService
    {
        /// <summary>
        /// Detection cycle timer
        /// </summary>
        private readonly Timer _timer;
        /// <summary>
        /// Detection cycle (seconds)
        /// </summary>
        private int _monitorInterval = 10;
        /// <summary>
        /// List of applications to guard
        /// </summary>
        private List<DaemonApplicationInfo> _daemonApps { get; set; }

        public HealthMonitorService()
        {
            // Initialize the list of applications to be guarded
            // In a real project, you can put the initialization parameters here in the configuration file / database / cache (how convenient it is)
            _daemonApps = new List<DaemonApplicationInfo> {
                new DaemonApplicationInfo {
                    ProcessName = Topshell of Demo. Client, // Please fill in as you see fit
                    AppDisplayName = Topshell of Demo Client, // Please fill in as you see fit
                    AppFilePath = @ "D: Projects github TopshelfDemoService TopshelfDemo. Client bin Debug TopshelfDemo. Client. Exe" // Please fill in the path here according to your actual situation.
                }
            };
            _timer = new Timer(_monitorInterval*1000) { AutoReset = true };
            _timer.Elapsed += (sender, eventArgs) => Monitor();
        }

        /// <summary>
        /// Method of daemon application
        /// </summary>
        private void Monitor()
        {
            foreach (var app in _daemonApps)
            {
                // Determine that the current process is saved and started
                if (ProcessorHelper.IsProcessExists(app.ProcessName))
                {
                    Console.WriteLine("Application[{0}] already exists.", app.ProcessName);
                    return;
                }
                try
                {
                    // If there is no process name to be guarded in the current host process list, start the corresponding application for the process
                    ProcessorHelper.RunProcess(app.AppFilePath, app.Args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Start application failed:{0}", ex);
                }
            }            
        }

        public void Start()
        {
            _timer.Start();
        }
        public void Stop()
        {
            _timer.Stop();
        }
    }
}

New classDaemonApplicationInfo.csandProcessorHelper.csWrite the following code.

DaemonApplicationInfo.cs (application entity classes to be guarded):

namespace TopshelfDemoService
{
    /// <summary>
    /// Application entities to be guarded
    /// </summary>
    public class DaemonApplicationInfo
    {
        /// <summary>
        /// Name displayed in the process
        /// </summary>
        public string ProcessName { get; set; }
        /// <summary>
        /// Application installation path
        /// </summary>
        public string AppFilePath { get; set; }
        /// <summary>
        /// Name of application
        /// </summary>
        public string AppDisplayName { get; set; }

        /// <summary>
        // / parameter
        /// </summary>
        public string Args { get; set; }
    }
}

ProcessorHelper.cs (Process Processing Help Class):

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace TopshelfDemoService
{
    /// <summary>
    /// Process Processing Help Class
    /// </summary>
    internal class ProcessorHelper
    {
        /// <summary>
        /// Get a list (collection) of all processes on the current computer
        /// </summary>
        /// <returns></returns>
        public static List<Process> GetProcessList()
        {
            return GetProcesses().ToList();
        }

        /// <summary>
        /// Get a list (array) of all processes on the current computer
        /// </summary>
        /// <returns></returns>
        public static Process[] GetProcesses()
        {
            var processList = Process.GetProcesses();
            return processList;
        }

        /// <summary>
        /// Determine whether the specified process exists
        /// </summary>
        /// <param name="processName"></param>
        /// <returns></returns>
        public static bool IsProcessExists(string processName)
        {
            return Process.GetProcessesByName(processName).Length > 0;
        }

        /// <summary>
        /// Start an application with a specified path
        /// </summary>
        /// <param name="applicationPath"></param>
        /// <param name="args"></param>
        public static void RunProcess(string applicationPath, string args = "")
        {
            try
            {
                var psi = new ProcessStartInfo
                {
                    FileName = applicationPath,
                    WindowStyle = ProcessWindowStyle.Normal,
                    Arguments = args
                };
                Process.Start(psi);
            }
            catch{}
        }
    }
}

After completing the above coding, we shut down the project program [TopshelfDemo. Client] and [TopshelfDemoService] first (if running), and then run the project [TopshelfDemoService]. Here is the moment to witness the miracle:

Create a Topshell-based application daemon (service) in C#/.NET application development

As you can see, the daemon [TopshelfDemoService] automatically starts the client program [TopshelfDemo. Client. exe], and only starts one client instance program. When we close the client, the next time the daemon detects, the client program will be restarted.

remaining problems

If you are happily installing TopshelfDemoService as a Windows service, you may encounter the problem that the daemon runs normally, the client program can also be protected and started normally, and the client process can be found in the Windows Task Manager, but the UI interface of the client program can not be seen.

What’s the matter??? Is there something wrong??? How should we solve it????

Listen to the next decomposition (to be continued)…

Okay, that’s all for today’s sharing of creating a Topshell-based application daemon (service) in C#/.NET application development.

I’m Rector. I hope this article will help you with C#/. NET development.

Source code download

The hosted address of this sample code can be found in its original source: the sample code download address

Recommended Today

Array of algorithms — sum of three numbers

Sum of three numbers difficultysecondary Here is an array of N integersnums, judgmentnumsAre there three elements a, B, C in a such that a + B + C = 0? Please find all triples that satisfy the condition and do not repeat.be careful:The answer cannot contain duplicate triples. Example:Given array nums = [- 1, 0, […]