.NET进程守护服务

一、新建一个Windows服务项目,取名ProcessDaemonServiceTest

用到是.NET Framework 4的框架 

新建后的样式:

 二、右击Service1.cs文件查看代码

三、添加应用程序配置文件App.config,在文件里增加如下配置

<?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>

 四、在Service1.cs代码文件中引入【Cjwdev.WindowsApi】程序集

using Cjwdev.WindowsApi;

五、编写服务

1、在构造函数里处理配置消息,读取配置的路径

//存放路径的数组
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、编写打开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、在OnStart方法中创建Timer定时器,添加事件,调用OpenExe方法,并启动

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;
}

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);
        }
    }
}

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);
        }
    }
}

六、为服务添加安装程序

点击Service1.cs,在左侧界面内右击,选择“添加安装程序”

会生成ProjectInstaller.cs文件,同时生产serviceProcessInstaller1和serviceInstaller1两个组件

1、设置serviceInstaller1组件的属性,右击它选择属性

默认属性如下:

 

其中:

        Name:表示控件的名称

        Description:是安装后的描述

        DisplayName:显示的名称

        ServiceName: 指示系统用于标识此服务的名称。此属性必须与要安装的服务的 ServiceBase.ServiceName 相同

        StartType:表示服务的启动方式。默认为 Manual,指定在重新启动后服务将不会自动启动。Automatic:自动启动。Disabled:禁用

设置 StartType 来指定该服务是在重新启动后自动启动,还是必须由用户手动启动。服务还可以被禁用,指定在启用以前不能被手动或以编程方式启动。

 2、设置serviceProcessInstaller1的属性,右击它选择属性

 

        其中:        

        Account:获取或设置运行该服务应用程序时所使用的帐户类型 

        LocalService:充当本地计算机上非特权用户的帐户,该帐户将匿名凭据提供给所有远程服务器

        NetworkService:提供广泛的本地特权的帐户,该帐户将计算机的凭据提供给所有远程服务器

        LocalSystem:服务控制管理员使用的帐户,它具有本地计算机上的许多权限并作为网络上的计算机

        User:由网络上特定的用户定义的帐户。如果为 ServiceProcessInstaller.Account 成员指定 User,则会使系统在安装服务时提示输入有效的用户名和密码,除非您为 ServiceProcessInstaller 实例的 Username 和 Password 这两个属性设置值

七、注册、启动、停止和卸载服务

使用CMD调用安装程序工具【InstallUtil.exe】注册服务,需要以管理员身份运行CMD

1、注册服务 

使用指令:InstallUtil.exe ProcessDaemonServiceTest.exe

 2、启动服务

使用命令:net start 服务名

 

3、 停止服务

使用命令:net stop 服务名

4、卸载服务

使用指令:InstallUtil.exe -u ProcessDaemonServiceTest.exe

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows守护进程(Windows Service)是在Windows操作系统上运行的后台进程,可以在系统启动时自动启动,并且在后台持续运行,提供某种服务或功能。与常规的应用程序不同,守护进程通常不与用户界面交互,而是在系统后台运行,无需用户登录或交互。 Windows守护进程可以执行各种任务,例如定期执行某些操作、提供网络服务、监控硬件设备等。它们可以通过Windows服务管理器进行配置和控制,可以设置为自动启动、手动启动或禁用。 开发Windows守护进程可以使用多种编程语言和开发框架,例如C++、C#、VB.NET等。在开发过程中,通常需要处理以下几个关键步骤: 1. 定义服务功能:确定守护进程需要提供的服务或功能,包括定义服务名称、描述、启动类型等。 2. 编写服务代码:使用所选的编程语言和开发框架编写守护进程的代码逻辑,包括启动、停止、暂停、恢复等操作。 3. 安装和配置服务:将守护进程安装到操作系统中,并进行必要的配置,例如设置启动类型、依赖关系等。 4. 控制和监控服务:使用Windows服务管理器或命令行工具来控制和监控守护进程的状态,例如启动、停止、暂停、恢复等操作。 需要注意的是,开发Windows守护进程需要一定的系统编程知识和理解操作系统的相关原理。在开发过程中,还需要考虑服务的稳定性、安全性和性能等方面的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值