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