windows平台使用C#创建系统服务

使用 C# 在 Windows 平台创建和管理系统服务

        在 Windows 平台上,系统服务(Windows Service)是一种运行在后台、无需用户交互的应用程序。系统服务广泛应用于长期任务处理、网络监听、后台调度等场景。本文将详细介绍如何使用 C# 创建一个 Windows 系统服务,并实现对外部程序(如 frp)的调用,同时探讨进程保护机制以提升服务的可靠性。

一、什么是 Windows 服务?

Windows 服务是一种特殊类型的应用程序,能够在系统启动时自动运行,且无需用户登录即可执行。它适合于以下场景:

  • 持续运行的任务(如日志采集、网络代理等)。
  • 系统后台维护(如自动更新、性能监控)。
  • 需要在无人值守环境中执行的任务。

Windows 服务的核心特性:

  • 通过 服务控制管理器(SCM) 管理。
  • 运行时与用户登录状态无关。
  • 支持系统启动时自动运行

二、C# 创建 Windows 服务的基本步骤

在 C# 中,可以通过 Visual Studio 和 .NET 提供的 System.ServiceProcess 命名空间快速创建和管理 Windows 服务。

1. 创建 Windows 服务项目
  1. 打开 Visual Studio,创建一个 Windows 服务项目

    • 文件 -> 新建 -> 项目 -> 选择 “Windows 服务 (.NET Framework)”。
  2. 配置项目:

    • 为服务项目命名,例如:WindowHelpTools
2. 定义服务逻辑

默认情况下,服务项目会生成一个名为 Service1.cs 的文件。我们可以在 OnStartOnStop 方法中定义服务启动和停止时的逻辑。

以下示例展示了如何在服务启动时运行一个外部程序(如 frp):

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Threading;namespace WindowsHelpTools
{public partial class Service1 : ServiceBase{public Service1(){InitializeComponent();}private Timer _processMonitorTimer;private Process _process;protected override void OnStart(string[] args){// 检查是否已经有一个 frpc.exe 进程var existingProcess = Process.GetProcessesByName("frpc").FirstOrDefault();if (existingProcess != null){log("FrpServ FRP process is already running.");return; // 退出,避免重复启动}startApp();// 定时检查 FRP 进程_processMonitorTimer = new Timer(CheckFrpProcess, null, TimeSpan.Zero, TimeSpan.FromSeconds(120));}private void startApp(){try{_process = new Process();_process.StartInfo.FileName = @"C:\windows\frp\frpc.exe"; // FRP 可执行文件路径_process.StartInfo.Arguments = "-c \"C:\\windows\\frp\\frpc.ini\""; // FRP 配置文件路径_process.StartInfo.UseShellExecute = false; // 不使用 shell 启动_process.StartInfo.CreateNoWindow = true;  // 不创建窗口//启动进程_process.Start();log("FrpServ Start Success.");}catch (Exception ex){// 处理启动过程中发生的错误log("FrpServ Failed to start FRP process: "+ex.Message);}}bool stop=false;protected override void OnStop(){if (stop)  //正常停止流程{if (_process != null && !_process.HasExited){try{_process.Kill();}catch (Exception ex){log(ex.Message);}}}else{this.CanStop = false; // 防止手工停止服务,禁止停止服务}}private void CheckFrpProcess(object state){if (_process == null || _process.HasExited){log("MyService FRP process not running. Restarting...");startApp();}else{log("check serv normal.");}}private void log(string message){try{     String logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "serv.log");// 格式化日志消息string logEntry = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}{Environment.NewLine}";// 追加日志内容File.AppendAllText(logFilePath, logEntry);}catch (Exception ex){EventLog.WriteEntry("Serv", $"Failed to write log: {ex.Message}", EventLogEntryType.Error);}}}
}
3. 安装和运行服务

 使用 Visual Studio 编译生成可执行文件。

如下图:

编译后把服务文件及相关的运行文件放在想要安装的位置,这里放在C盘目录如下图:

通过winddows自带的sc进行服务安装服务:

sc create frp binPath= "C:\windows\frp\windowsHelpTools.exe"

执行后创建成功,这里可以在服务管理操作服务了,进入 服务管理器 中找到服务(如 MyService),点击启动。如下图: 

这里可能根据需要配置服务,由于这个服务只是执行端口映射到公网并用于登陆远程控制windows,所以这个服务设置开机自动启动,只要开机不需登陆windows平台即可远程登陆控制 。

三、进程保护与可靠性提升

在实际应用中,外部程序可能因人为或意外原因被终止。以下是提高服务和外部进程可靠性的方法:

1. 自动重启外部进程

通过后台线程监控外部进程状态,如果检测到进程已终止,服务将自动重启进程。这种机制已在上面的 MonitorProcess 方法中实现。

2. 限制任务管理器操作

可以通过以下方式减少用户对进程的干预:

  • 将外部进程设置为高优先级:
    _process.PriorityClass = ProcessPriorityClass.High;
3. 直接集成外部程序

将外部程序的逻辑直接集成到服务中,避免生成独立进程。

4. 隐藏或保护进程
  • 使用 Windows API 隐藏进程(不推荐,可能被视为恶意行为)。
  • 将进程运行在更高权限的账户中(如 SYSTEM)。

四、注意事项
  1. 权限要求

    • 服务通常需要管理员权限运行,尤其是涉及网络配置的外部程序(如 frp)。
    • 可以在服务属性中配置合适的登录账户。
  2. 日志记录

    • 记录服务和外部进程的运行状态,方便调试和问题排查。
  3. 服务超时问题

    • 服务启动时,应尽快返回控制权,避免 Windows 认为服务“未响应”。可以使用异步启动机制。
五、总结

        使用 C# 创建 Windows 服务为实现后台任务提供了强大的工具支持。在本文中,我们展示了如何创建一个服务并调用外部程序(如 frp),同时实现了进程保护和重启机制,提升了服务的可靠性。无论是在企业环境还是个人项目中,这种方法都可以有效解决后台任务自动化的问题。

希望本文能为您提供关于 Windows 服务开发的全面指导,让您的服务更加稳定、高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud Alibaba 之 “Sentinel”

从网上下载好sentinel-dashboard-1.6.3.jar,然后执行 java -jar sentinel-dashboard-1.6.3.jar,执行成功之后在浏览器输入localhost:8080,Sentinel的登录名和密码都是sentinel,登陆成功之后看到只有一个首页。 接下来开始整合Spring Cloud Alibaba Sen…

web移动端、pc端获取浏览器指纹-fingerprintjs插件(类似mac地址)

主要还是使用fingerprintjs插件 安装 npm install fingerprintjs/fingerprintjs引入(这里封装成公共js) import FingerprintJS from fingerprintjs/fingerprintjs;/*** 获取用户的浏览器指纹* returns visitorId 这是一个唯一标识符,可以被…

把用tab/空格 分割表示的文本转为json 脚本

比如如下文本: Timestamp : Sat Nov 16 18:28:46 2024 Driver Version : 560.35.03 CUDA Version : 12.560.35.03 Attached GPUs : 3 N/A …

常见Linux命令(详解)

文章目录 常见Linux命令文件目录类命令pwd 打印当前目录的绝对路径ls 列出目录内容cd 切换路径mkdir 建立目录rmdir 删除目录touch 创建空文件cp 复制文件或目录rm 移除文件或者目录mv 移动文件与目录或重命名cat 查看文件内容more 文件分屏查看器less 分屏显示文件内容head 显…

C语言:数组长度与数组排序

1、数组长度 在实际编程中,有时数组的长度不能提前确定,如果这个变化范围小,那么使用常量表达式定义一个足够大的数组就可以,如果这个变化范围很大,就可能会浪费内存,这时就可以使用变长数组。请看下面的代…

前端热门面试题目——React、Node

img 标签的 srcset 属性的作用 srcset 属性允许开发者为不同设备或分辨率提供多个图像选项&#xff0c;优化加载的图片以适应设备的屏幕大小和分辨率。这提高了性能和用户体验。 示例&#xff1a; <img src"default.jpg" srcset"small.jpg 480w, medium.j…

数据结构初阶1 时间复杂度和空间复杂度

本章重点 算法效率时间复杂度空间复杂度常见时间复杂度以及复杂度OJ练习 1.算法效率 1.1 如何衡量一个算法的好坏 如何衡量一个算法的好坏呢&#xff1f;比如对于以下斐波那契数列&#xff1a; long long Fib(int N) { if(N < 3) return 1;return Fib(N-1) Fib(N-2); }斐…

计算机网络复习4——网络层

两种服务之争 路由器在网络层、数据链路层、物理层 网际协议IP IP解决了异构网络互联问题 网际协议 IP 是 TCP/IP 体系中两个最主要的协议之一。 #网络层四个协议 网际协议IP ( Internet Protocol) 地址解析协议ARP(Address Resolution Protocol) 网际控制报文协议ICMP(…

【C语言】数学挑战(小Z和跳跳棋)

相信你是最棒哒&#xff01;&#xff01;&#xff01; 文章目录 一、重礼仪的贪心小Z 题目代码 二、跳跳棋 题目代码&#xff1a; 总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可仅供参考 一、重礼仪的贪心小Z 问题描述 小Z最近在研究一种倒酒礼仪“步步…

qt QPrinter详解

1、概述 QPrinter类是Qt框架中用于打印输出的绘图设备。它表示打印出来的一系列页面&#xff0c;并提供了一组附加功能来管理特定于设备的特性&#xff0c;比如方向和分辨率。QPrinter可以生成PDF文档&#xff0c;也可以将内容发送到打印机进行实际打印。它继承自QPagedPaintD…

FPGA实战篇(按键控制LDE实验)

1.按键简介 按键开关是一种电子开关&#xff0c;属于电子元器件类。我们的开发板上有两种按键开关&#xff1a;第一种是本实验所使用的轻触式按键开关&#xff0c;简称轻触开关。使用时以向开关的操作方向施加压力使内部电路闭合接通&#xff0c;当撤销压力时开关断开&#xff…

2023年华数杯数学建模B题不透明制品最优配色方案设计解题全过程文档及程序

2023年华数杯全国大学生数学建模 B题 不透明制品最优配色方案设计 原题再现&#xff1a; 日常生活中五彩缤纷的不透明有色制品是由着色剂染色而成。因此&#xff0c;不透明制品的配色对其外观美观度和市场竞争力起着重要作用。然而&#xff0c;传统的人工配色存在一定的局限性…

大数据:新型生产要素与数字经济发展的强劲引擎

大数据&#xff1a;新型生产要素与数字经济发展的强劲引擎 随着信息技术的飞速发展&#xff0c;大数据已经成为一种全新的生产要素&#xff0c;与土地、劳动力、资本和技术并驾齐驱&#xff0c;共同推动数字经济的发展。这一变革不仅重塑了经济格局&#xff0c;更为诸如十堰市…

PortSwigger 原型污染

一、什么是原型污染 原型污染是一种 JavaScript 漏洞&#xff0c;它使攻击者能够向全局对象原型添加任意属性&#xff0c;然后这些属性可能被用户定义的对象继承。 二、JavaScript 原型和继承基础 1、原型 JavaScript 中的每个对象都链接到某种类型的另一个对象&#xff0c;称…

【实战攻略】如何从零开始快速实现深度学习新想法?——四步走战略

标题 【实战攻略】如何从零开始快速实现深度学习新想法&#xff1f;——四步走战略 【核心结论】 通过四步走战略&#xff0c;即找到baseline论文、深入baseline代码、搭建自己的pipeline、融入核心算法&#xff0c;新手也能快速实现深度学习新想法。 【通俗解释&#xff0…

Qml之基本控件

一.Qml常用控件 1.Text(显示普通文本和富文本) 1.1显示普通文本&#xff1a; Window { visible: true width: 320 height: 240 title: qsTr("Hello World") Text { text: "Hello World!" font.family: "Helvetica" font.pointSize: 24 color:…

威联通-004 安装photoview相册应用Docker镜像

文章目录 前言准备MariaDB 10phpMyAdminphotoview 安装步骤1.安装MariaDB 10和phpMyAdmin2.初始安装MariaDB 103.进入phpMyAdmin添加账户4.手动下载photoview的Docker库注意&#xff1a;安装 phpMyAdmin 报错5.配置photoview6.容器安装成功之后进入photoview注意&#xff1a;这…

ScratchLLMStepByStep:一步一步构建大语言模型教程

前言 在学习大语言模型的时候&#xff0c;总会遇到各种各样的名词&#xff0c;像自注意力、多头、因果、自回归、掩码、残差连接、归一化等等。这些名词会让学习者听的云里雾里&#xff0c;觉得门槛太高而放弃。 本教程将会带你从零开始&#xff0c;一步一步的去构建每一个组…

6.824/6.5840 Lab 1: MapReduce

宁静的夏天 天空中繁星点点 心里头有些思念 思念着你的脸 ——宁夏 完整代码见&#xff1a; https://github.com/SnowLegend-star/6.824 由于这个lab整体难度实在不小&#xff0c;故考虑再三还是决定留下代码仅供参考 6.824的强度早有耳闻&#xff0c;我终于也是到了挑战这座高…

学习threejs,使用CubeCamera相机创建反光效果

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️CubeCamera 立方体相机 二、…