Servicio de demonio de proceso .NET

1. Cree un nuevo proyecto de servicio de Windows y asígnele el nombre ProcessDaemonServiceTest.

El framework utilizado es .NET Framework 4 

Nuevo estilo:

 2. Haga clic derecho en el archivo Service1.cs para ver el código.

3. Agregue el archivo de configuración de la aplicación App.config y agregue la siguiente configuración en el archivo

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <appSettings>
    <add key="Time" value="3000"/>
    <add key="Path1" value="D:\Test1\Test1.exe"/>
    <add key="Path2" value="D:\Test2\Test2.exe"/>
  </appSettings>
</configuration>

 4. Introduzca el ensamblado [Cjwdev.WindowsApi] en el archivo de código Service1.cs.

using Cjwdev.WindowsApi;

5. Servicios de redacción

1. Procese el mensaje de configuración en el constructor y lea la ruta de configuración.

//存放路径的数组
private static string[] appStartPath = new string[] { };
NameValueCollection appsettings = ConfigurationManager.AppSettings;
string[] names = ConfigurationManager.AppSettings.AllKeys;

public Service1()
{
    List<string> asp = appStartPath.ToList();
    for (int i = 0; i < appsettings.Count; i++)
    {
        string key = names[i];
        if (key.Contains("Path"))
        {
            string path = ConfigurationManager.AppSettings[key];
            asp.Add(path);
        }
    }
    appStartPath = asp.ToArray();

    InitializeComponent();
}

2. Escriba un método de evento para abrir el programa exe.

private void OpenExe(object sender, System.Timers.ElapsedEventArgs e)
{
    //句柄
    IntPtr userTokenHandle = IntPtr.Zero;
    ApiDefinitions.WTSQueryUserToken(ApiDefinitions.WTSGetActiveConsoleSessionId(), ref userTokenHandle);

    ApiDefinitions.PROCESS_INFORMATION procInfo = new ApiDefinitions.PROCESS_INFORMATION();
    ApiDefinitions.STARTUPINFO startInfo = new ApiDefinitions.STARTUPINFO();
    startInfo.cb = (uint)System.Runtime.InteropServices.Marshal.SizeOf(startInfo);

    //使用循环,校验程序是否以及打开(exe程序名与进程名需要一致),如果未打开则调用方法CreateProcessAsUser打开
    for (int i = 0; i < appStartPath.Length; i++)
    {
        string appName = appStartPath[i].Split('\\')[appStartPath[i].Split('\\').Length - 1].Split('.')[0];
        //是否打开的标志位
        bool runFlag = false;
        Process[] myProcesses = Process.GetProcesses();
        //进程名是否存在
        foreach (Process myProcess in myProcesses)
        {
            if (myProcess.ProcessName.CompareTo(appName) == 0)
            {
                runFlag = true;
            }
        }
        if (!runFlag)
        {
            ApiDefinitions.CreateProcessAsUser(
                userTokenHandle,//句柄
                appStartPath[i],//路径
                "",//命令
                IntPtr.Zero,
                IntPtr.Zero,
                false,
                0,
                IntPtr.Zero,
                null,
                ref startInfo,
                out procInfo);
        }
    }
    if (userTokenHandle != IntPtr.Zero)
        //关闭句柄
        ApiDefinitions.CloseHandle(userTokenHandle);
}

3. Cree un temporizador en el método OnStart, agregue eventos, llame al método OpenExe y comience

protected override void OnStart(string[] args)
{
    //定时器
    System.Timers.Timer timer;

    timer = new System.Timers.Timer();
    //设置计时器事件间隔执行时间
    timer.Interval = Convert.ToInt32(ConfigurationManager.AppSettings["Time"]);
    //添加绑定事件,达到间隔时发生
    timer.Elapsed += new System.Timers.ElapsedEventHandler(OpenExe);
    //启动定时器
    timer.Enabled = true;
}

Código completo de Service1.cs:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using Cjwdev.WindowsApi;
using System.Configuration;
using System.Collections.Specialized;

namespace ProcessDaemonServiceTest
{
    public partial class Service1 : ServiceBase
    {
        private static string[] appStartPath = new string[] { };
        NameValueCollection appsettings = ConfigurationManager.AppSettings;
        string[] names = ConfigurationManager.AppSettings.AllKeys;
        //定时器
        System.Timers.Timer timer = new System.Timers.Timer();

        public Service1()
        {
            List<string> asp = appStartPath.ToList();
            for (int i = 0; i < appsettings.Count; i++)
            {
                string key = names[i];
                if (key.Contains("Path"))
                {
                    string path = ConfigurationManager.AppSettings[key];
                    asp.Add(path);
                }
            }
            appStartPath = asp.ToArray();

            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            //设置计时器事件间隔执行时间
            timer.Interval = Convert.ToInt32(ConfigurationManager.AppSettings["Time"]);
            //添加绑定事件,达到间隔时发生
            timer.Elapsed += new System.Timers.ElapsedEventHandler(OpenExe);
            //启动定时器
            timer.Enabled = true;
        }

        protected override void OnStop()
        {
            timer.Enabled = false;
        }

        private void OpenExe(object sender, System.Timers.ElapsedEventArgs e)
        {
            //句柄
            IntPtr userTokenHandle = IntPtr.Zero;
            ApiDefinitions.WTSQueryUserToken(ApiDefinitions.WTSGetActiveConsoleSessionId(), ref userTokenHandle);

            ApiDefinitions.PROCESS_INFORMATION procInfo = new ApiDefinitions.PROCESS_INFORMATION();
            ApiDefinitions.STARTUPINFO startInfo = new ApiDefinitions.STARTUPINFO();
            startInfo.cb = (uint)System.Runtime.InteropServices.Marshal.SizeOf(startInfo);

            //使用循环,校验程序是否以及打开(exe程序名与进程名需要一致),如果未打开则调用方法CreateProcessAsUser打开
            for (int i = 0; i < appStartPath.Length; i++)
            {
                string appName = appStartPath[i].Split('\\')[appStartPath[i].Split('\\').Length - 1].Split('.')[0];
                //是否打开的标志位
                bool runFlag = false;
                Process[] myProcesses = Process.GetProcesses();
                //进程名是否存在
                foreach (Process myProcess in myProcesses)
                {
                    if (myProcess.ProcessName.CompareTo(appName) == 0)
                    {
                        runFlag = true;
                    }
                }
                if (!runFlag)
                {
                    ApiDefinitions.CreateProcessAsUser(
                        userTokenHandle,//句柄
                        appStartPath[i],//路径
                        "",//命令
                        IntPtr.Zero,
                        IntPtr.Zero,
                        false,
                        0,
                        IntPtr.Zero,
                        null,
                        ref startInfo,
                        out procInfo);
                }
            }
            if (userTokenHandle != IntPtr.Zero)
                ApiDefinitions.CloseHandle(userTokenHandle);
        }
    }
}

Entrada del programa Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace ProcessDaemonServiceTest
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new Service1()
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
}

6. Agregue un instalador para el servicio.

Haga clic en Service1.cs, haga clic derecho en la interfaz izquierda y seleccione "Agregar instalador"

Se generará el archivo ProjectInstaller.cs y se generarán dos componentes, serviceProcessInstaller1 y serviceInstaller1.

1. Configure las propiedades del componente serviceInstaller1, haga clic derecho y seleccione Propiedades

Las propiedades predeterminadas son las siguientes:

 

en:

        Nombre: Indica el nombre del control.

        Descripción: es la descripción después de la instalación.

        DisplayName: nombre mostrado

        ServiceName: Indica el nombre utilizado por el sistema para identificar este servicio. Esta propiedad debe ser la misma que ServiceBase.ServiceName del servicio que se está instalando.

        StartType: Indica cómo se inicia el servicio. El valor predeterminado es  Manual , que especifica que el servicio no se iniciará automáticamente después de reiniciar. Automático : inicia automáticamente. Deshabilitado : deshabilitado

Establezca  StartType  para especificar si el servicio se inicia automáticamente después de un reinicio o si el usuario debe iniciarlo manualmente. Los servicios también se pueden deshabilitar, especificando que no se pueden iniciar manualmente o mediante programación antes de habilitarlos.

 2. Establezca las propiedades de serviceProcessInstaller1, haga clic derecho y seleccione Propiedades

 

        en:        

        Cuenta: obtiene o establece el tipo de cuenta utilizada al ejecutar la aplicación de servicio. 

        LocalService: actúa como una cuenta de usuario sin privilegios en la máquina local que proporciona credenciales anónimas a todos los servidores remotos.

        NetworkService: una cuenta que proporciona amplios privilegios locales que proporciona las credenciales de la computadora a todos los servidores remotos.

        LocalSystem: Cuenta utilizada por el administrador de control de servicios, que tiene muchos permisos en la computadora local y como computadora en la red.

        Usuario: una cuenta definida por un usuario específico en la red. Al especificar un usuario para el miembro ServiceProcessInstaller.Account, el sistema solicita un nombre de usuario y una contraseña válidos al instalar el servicio, a menos que establezca valores para las propiedades Nombre de usuario y Contraseña de la instancia de ServiceProcessInstaller.

7. Registrar, iniciar, detener y desinstalar servicios.

Utilice CMD para llamar a la herramienta de instalación [InstallUtil.exe] para registrar el servicio. Debe ejecutar CMD como administrador.

1. Servicio de registro 

Instrucciones de uso: InstallUtil.exe ProcessDaemonServiceTest.exe

 2. Inicie el servicio

Utilice el comando: nombre del servicio net start

 

3. Detener el servicio

Utilice el comando: nombre del servicio net stop

4. Desinstalar el servicio

Instrucciones de uso: InstallUtil.exe -u ProcessDaemonServiceTest.exe

 

Guess you like

Origin blog.csdn.net/weixin_50478033/article/details/133275528