原文:Creating Windows Services In .NET Core – Part 1 – The “Microsoft” Way

创建Windows服务来运行批处理任务或者运行后台任务,是一种非常常见的模式,但是由于云服务(Amazon Lambda, Azure WebJobs以及Azure Functions)的激增,你可能不会经常使用Windows服务了。个人而言,我非常喜欢使用Azure WebJobs, 因为我可以直接编写一个控制台程序,而不需要考虑如何云中运行它,一个批处理文件可以将其装换成一个自动化任务,并且可以保证7*24小时的运行。

但是也许你还没有使用云服务,或者你有一堆要作为Windows服务运行的旧版应用程序需要转换为.NET Core, 但是不能完全将他们转换为“无服务器”(serverless)应用。那么这边文章就是适合你的。

在许多方面,.NET Core中的Windows服务和.NET Framework中的Windows服务完全相同。但是,在编写服务的时候,你可能会遇到一些小问题。此外,本文中,我们仅介绍“Microsoft”方式的Windows服务创建,在后续,我会继续介绍如何使用第三方库TopShelf来简化这该过程。

由于Visual Studio没有提供创建Windows服务的模板,所以我们需要通过创建控制台程序的方式来创建一个Windows服务。

创建完成之后,我们需要安装一个Nuget程序包,这个程序包会将一些Windows特定的API添加到.NET Core中,这些API实际上已经在完整框架中提供了,但是其中许多是Windows特有的,例如Windows服务。因此, 它们并没有包含在.NET Core的基础库中,但是可以通过将Nuget程序包的方式引入到.NET Core中。

Install-Package Microsoft.Windows.Compatibility

以上引入的Nuget程序包中,最让我们感兴趣的是ServiceBase类。这是一个用于编写Windows服务的基类,它提供了一系列的事件钩子,包含服务启动、结束、暂停等。

下面呢,我们将在代码中创建一个类,这个类负责将一些简单的日志输出到一个临时文件中。我们将使用这个例子来了解其中的原理。我们的代码如下:

class LoggingService : ServiceBase
{private const string _logFileLocation = @"C:\temp\servicelog.txt";private void Log(string logMessage){Directory.CreateDirectory(Path.GetDirectoryName(_logFileLocation));File.AppendAllText(_logFileLocation, DateTime.UtcNow.ToString() + " : " + logMessage + Environment.NewLine);}protected override void OnStart(string[] args){Log("Starting");base.OnStart(args);}protected override void OnStop(){Log("Stopping");base.OnStop();}protected override void OnPause(){Log("Pausing");base.OnPause();}
}

所以这里你会注意到,我们的类是继承了ServiceBase类,并且我们重写了几个事件方法,输出了一些日志。在服务启动时,会触发OnStart事件,在服务终止的时候,会触发OnStop事件。这里我们不应该将过于繁重的任务放置在OnStart事件中来处理。

如果我们想从Main方式中启动这个服务,代码非常的简单。

static void Main(string[] args)
{ServiceBase.Run(new LoggingService());
}

以上就是全部代码。

在发布服务的时候,我们不可能仅依靠Visual Studio来构建我们所需要的服务,我们还需要专门针对Windows运行时进行构建。为此,我们需要在项目根目录的命令提示符下运行以下命令。注意,这里我们传入了一个-r标记来告诉它要构建那个平台。

dotnet publish -r win-x64 -c Release

命令运行完毕之后,我们可以检查以下/bin/release/netcoreappX.X/publish目录,我们可以找到所有的发布代码,但是最重要的是,这里我们可以得到一个可执行的exe文件。如果我们不指定运行时,我们只会获得一个.NET Core的dll程序集,使用这个程序集,我们是没有办法创建Windows服务的。

现在我们可以将这个发布目录移动带其他的任何地方,但是现在我们就暂时使用当前的发布目录。

下一步,我们需要使用管理员角色打开一个命令提示符,然后输入一下命令。

sc create TestService BinPath=C:\full\path\to\publish\dir\WindowsServiceExample.exe

SC命令是一个标准的Windows命令(与.NET Core无关),它可以用来安装Windows服务。这里我们将我们的测试服务命名为TestService,更重要的是,我们通过BinPath参数指定了可执行exe文件。

运行之后,我们应该会得到以下结果。

[SC] CreateService SUCCESS

然后我们要做的就是启动服务。

sc start TestService

现在我们可以查看一下我们的日志文件,查看服务的运行情况。

如果想要停止并删除服务,我们可以使用一下命令。

sc stop TestService
sc delete TestService

在这里,我真的认为,使用"Microsoft"的方式注定会失败。因为调试服务实在是太繁琐了。

首先,我们将ServiceBase中重写的方法设置为受保护,这意味着我们无法在类之外访问它们,这使得调试它们变得更加困难。这里我发现最好的方法是为每个事件提供一个public方法, 并在受保护方法中调用这些public方法来完成功能,这虽然有点混乱,

public void OnStartPublic(string[] args)
{Log("Starting");
}protected override void OnStart(string[] args)
{OnStartPublic(args);base.OnStart(args);
}

但是至少我们可以做如下了事情了。

static void Main(string[] args)
{var loggingService = new LoggingService();if (true){loggingService.OnStartPublic(new string[0]);while(true){Thread.Sleep(1000);}}else{ServiceBase.Run(new LoggingService());}
}

你的另一个选择是,在调试模式下进行项目发布,安装服务,然后附加调试器。实际上,这是Microsoft建议你使用的方式,但是我认为这简直一团糟。

实际上,我们可以在这里做一些其他非常有用的事情, 比如我们可以通过创建一个install.bat批处理文件来为我们运行SC Create命令。但我认为,上面我们看到的调试问题,已经让我不再想使用这种方式了。幸运的是,有一个名为Topshelf的库可以帮助我们减轻很多麻烦,在本系列的下一部分中,我们将研究如何它。

使用.NET Core创建Windows服务(一) - 使用官方推荐方式相关推荐

  1. 使用.NET Core创建Windows服务 - 使用.NET Core工作器方式

    原文:Creating Windows Services In .NET Core – Part 3 – The ".NET Core Worker" Way 作者:Dotnet ...

  2. 使用.NET Core创建Windows服务(二) - 使用Topshelf方式

    原文:Creating Windows Services In .NET Core – Part 2 – The "Topshelf" Way 作者:Dotnet Core Tut ...

  3. 使用.NET Core创建Windows服务(二) - 使用Topshelf方式

    使用.NET Core创建Windows服务 使用微软推荐方式 使用Topshelf方式 在前一篇文章中,我给大家介绍了,如何基于微软推荐方式使用.NET Core创建Windows服务.我们发现使用 ...

  4. .NET Core 使用Topshelf方式创建Windows服务

    Topshelf是一个.NET Standard库,它消除了在.NET Framework和.NET Core中创建Windows服务的那些麻烦. 安装 Install-Package Topshel ...

  5. .NET 使用Topshelf方式创建Windows服务

    阅读目录 安装 代码 部署服务 调试服务 Topshelf是一个.NET Standard库,它消除了在.NET Framework和.NET Core中创建Windows服务的那些麻烦. 安装 In ...

  6. 用.NET创建Windows服务

    用.NET创建Windows服务 译者说明:我是通过翻译来学习C#的,文中涉及到的有Visual Studio.NET有关操作,我都根据中文版的VS.NET显示信息来处理的,可以让大家不致有误解. 作 ...

  7. 用C#创建Windows服务(Windows Services)

    转载自 hyslove 最终编辑 hyslove Windows服务在Visual Studio 以前的版本中叫NT服务,在VS.net启用了新的名称.用Visual C# 创建Windows服务不是 ...

  8. 杂记2:VS2013创建Windows服务实现自动发送邮件

    这篇随笔里,我将介绍如何用VS2013开发Windows服务项目,实现的功能是定时发送电子邮件. 开发环境:VS2013,SQL Server2008,采用C#语言开发 步骤一:创建Windows服务 ...

  9. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

    C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案 参考文章: (1)C#/.NET基于Topshelf创建Windows ...

最新文章

  1. 数据分析显示,疫情下数据科学家的薪水几乎未受影响
  2. 014_Collections常用方法
  3. CodeForces 1616H Keep XOR Low {a^b≤x} / CodeForces gym102331 Bitwise Xor {a^b≥x}(trie树 + 计数)
  4. php mysql 验证码代码_PHP_PHP 验证码的实现代码,checkcode.php 生成验证码图片, - phpStudy...
  5. JS:ES6-12 模块化
  6. 从硬件竞争到软实力PK——电视媒体竞争观察
  7. PatchGAN:Image-to-Image Translation with Conditional Adversarial Networks
  8. 【Python】SyntaxError: Non-ASCII character '\xe8' in file
  9. linux 端口映射 命令,linux查看端口映射命令
  10. 国二c语言程序设计分值分布,计算机二级分值
  11. 跨越鸿沟:计算机视觉-学术界与工业界的GAP有多大?
  12. JS常用的六种设计模式详解
  13. 开源主流分布式文件系统简单介绍
  14. deprecate node-sass@4.9.0 › request@~2.79.0 request has been deprecated, see https://github.com
  15. 2021年塔式起重机司机复审考试及塔式起重机司机考试试题
  16. 安卓:No static method decodeBase64,commen-code包里报错的信息
  17. 印象笔记粘贴HTML,【未解决】Mac中从印象笔记中拷贝图片后去VSCode中用Paste Image无法粘贴图片:There is not a image in clipboard...
  18. 大数定理与中心极限定理
  19. Python基础知识点六万字总结,爆肝一周熬夜完成【建议收藏】
  20. cad快速选择命令快捷键_学好CAD必须掌握的20个常用快捷键命令

热门文章

  1. android wifi
  2. VS2008、VS2010中如何屏蔽讨厌的MSVCR*.dll的引用
  3. 汇新杯┃拼多多黄峥:普通的创业者,不普通的朋友圈_创成汇
  4. easyui 排序实现
  5. java获取ResultSet长度
  6. ArcGISServer10安装与地图发布
  7. socket编程资料-网络收集
  8. .NET再出发!20岁生日快乐
  9. WPF 不遮挡任务栏最大化和全屏显示
  10. Hello Blazor:(13)查找HTML元素对应.razor文件