新建一个WindowsService之后,打开是这样的类;
partial class WindowsService : ServiceBase { public WindowsService() { InitializeComponent(); } protected override void OnStart(string[] args) { // TODO: 在此处添加代码以启动服务。 } protected override void OnStop() { // TODO: 在此处添加代码以执行停止服务所需的关闭操作。 } }
不想啰嗦,直接上代码,面向对象编程:
添加抽象父类:
internal abstract class BasicService { /// <summary> /// 服务名 /// </summary> protected string Name { get; } protected BasicService(string name) { Name = name; } public void Start() { Console.WriteLine($"服务[{Name}]正在启动"); try { OnStart(); Console.WriteLine($"服务[{Name}]已启动"); } catch (Exception ex) { Console.WriteLine($"服务[{Name}]启动时发生错误:" + ex.Message, ex); } } public void Stop() { Console.WriteLine($"服务[{Name}]正在停止"); try { OnStop(); Console.WriteLine($"服务[{Name}]已停止"); } catch (Exception ex) { Console.WriteLine($"服务[{Name}]停止时发生错误:" + ex.Message, ex); } } protected abstract void OnStart(); protected abstract void OnStop(); }
添加两个个子类示例:
/// <summary> /// WCF 宿主服务 /// </summary> internal class ApiHostService : BasicService { private ApiHost _host; public ApiHostService() : base(nameof(ApiHostService)) { } protected override void OnStart() { if (_host?.IsRuning == true) { Console.WriteLine($"[{Name}]:已运行的服务被重复启动,该操作被忽略"); return; } _host = new ApiHost(); _host.Start(); } protected override void OnStop() { _host.Stop(); } }
数据转发:
internal class DataDistributionSenderService : BasicService { public DataDistributionSenderService() : base(nameof(DataDistributionSenderService)) { } protected override void OnStart() { DataDistributor.Start(); } protected override void OnStop() { DataDistributor.Stop(); } }
MainServices: 启动各个子服务
/// <summary> /// 主服务:用于启动BasicService各个子服务 /// </summary> internal class MainService:BasicService { public WindowsService WindowsService; private readonly BasicService[] _subServices; public MainService() : base(nameof(MainService)) { _subServices = new BasicService[] { new ApiHostService(), new DataDistributionSenderService() }; } public MainService(WindowsService windowsService): this() { WindowsService = windowsService; } /// <summary> /// /// </summary> protected override void OnStart() { foreach (var subService in _subServices) { subService.Start(); Thread.Sleep(500); //Ensure start } } protected override void OnStop() { foreach (var subService in _subServices) { subService.Stop(); } } }
修改一下windowsSerivices类:
partial class WindowsService : ServiceBase { private readonly MainService _service; public WindowsService() { InitializeComponent(); //在这里捕获未经处理的异常,也就是发生在Try Catch块意外的异常 AppDomain.CurrentDomain.UnhandledException += delegate (object sender, UnhandledExceptionEventArgs args) { //将错误、警告、信息、成功审核或失败审核项与给定的消息文本一起写入事件日志;在系统日志中可以看到 EventLog.WriteEntry(args.ExceptionObject.ToString(), EventLogEntryType.Error); #region 或者写入日志文件 //try //{ // File.AppendAllText(@"xxx.log", args.ExceptionObject.ToString()); //} //// ReSharper disable once EmptyGeneralCatchClause //catch //{ //} #endregion }; _service = new MainService(this); } protected override void OnStart(string[] args) { _service.Start(); } protected override void OnStop() { _service.Stop(); } }
调试:
internal static class Program { #if DEBUG //http://www.pinvoke.net/default.aspx/kernel32.allocconsole [DllImport("kernel32.dll")]//引入kernel32.dll动态链接库 [return: MarshalAs(UnmanagedType.Bool)] private static extern bool AllocConsole(); #endif /// <summary> /// 应用程序的主入口点。 /// </summary> private static void Main(string[] args) { Thread.CurrentThread.Name = "Main"; #if DEBUG AllocConsole(); Console.WriteLine("Starting..."); #endif #if DEBUG
//-dubug 是我在项目属性->调试->命令行参数里面指定的 if (args.Length == 1 && args[0] == "-debug") { //Debug run code Here var svc = new MainService(); svc.Start(); Console.Write("Started. Press ENTER to stop..."); Console.ReadLine(); svc.Stop(); Console.Write("Stopped. Press ENTER to exit..."); Console.ReadLine(); return; } #endif var servicesToRun = new ServiceBase[] { new WindowsService() }; ServiceBase.Run(servicesToRun); } }
安装,关闭,删除:(记得添加安装程序)
- sc create serviceName binPath= "C:service.exe"
- InstallUtil.exe Path/WinService.exe,Path是路径
- https://support.microsoft.com/zh-cn/help/816169/how-to-create-a-setup-project-for-a-windows-service-application-in-vis
- https://www.cnblogs.com/weixing/archive/2013/08/23/3277781.html
- bat:
新建一个txt文件,把后缀改为.bat文件: 安装: @echo.服务启动...... @echo off @sc create WsTest binPath= "E:MySvnXXXXWindowServiceinRelease" @net start WsTest @sc config WsTest start= AUTO @echo off @echo.启动完毕! @pause 关闭: @echo.服务关闭 @echo off @net stop WsTest @echo off @echo.关闭结束! @pause 删除: @echo.服务删除 @echo off @sc delete WsTest @echo off @echo.删除结束! @pause