使用.NET Core创建Windows服务(一) - 使用官方推荐方式
原文:使用.NET Core创建Windows服务(一) - 使用官方推荐方式
原文:Creating Windows Services In .NET Core – Part 1 – The “Microsoft” Way
作者:Dotnet Core Tutorials
译者:Lamond Lu
译文:使用.NET Core创建Windows服务(一) - 使用官方推荐方式
创建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中。
下面我们就可以在Package Manager Console中输入以下命令。
CopyInstall-Package Microsoft.Windows.Compatibility
代码#
以上引入的Nuget程序包中,最让我们感兴趣的是ServiceBase
类。这是一个用于编写Windows服务的基类,它提供了一系列的事件钩子,包含服务启动、结束、暂停等。
下面呢,我们将在代码中创建一个类,这个类负责将一些简单的日志输出到一个临时文件中。我们将使用这个例子来了解其中的原理。我们的代码如下:
Copyclass 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
方式中启动这个服务,代码非常的简单。
Copystatic void Main(string[] args)
{
ServiceBase.Run(new LoggingService());
}
以上就是全部代码。
服务部署#
在发布服务的时候,我们不可能仅依靠Visual Studio来构建我们所需要的服务,我们还需要专门针对Windows运行时进行构建。为此,我们需要在项目根目录的命令提示符下运行以下命令。注意,这里我们传入了一个-r
标记来告诉它要构建那个平台。
Copydotnet publish -r win-x64 -c Release
命令运行完毕之后,我们可以检查以下/bin/release/netcoreappX.X/publish
目录,我们可以找到所有的发布代码,但是最重要的是,这里我们可以得到一个可执行的exe文件。如果我们不指定运行时,我们只会获得一个.NET Core的dll程序集,使用这个程序集,我们是没有办法创建Windows服务的。
现在我们可以将这个发布目录移动带其他的任何地方,但是现在我们就暂时使用当前的发布目录。
下一步,我们需要使用管理员角色打开一个命令提示符,然后输入一下命令。
Copysc create TestService BinPath=C:\full\path\to\publish\dir\WindowsServiceExample.exe
SC
命令是一个标准的Windows命令(与.NET Core无关),它可以用来安装Windows服务。这里我们将我们的测试服务命名为TestService
,更重要的是,我们通过BinPath
参数指定了可执行exe文件。
运行之后,我们应该会得到以下结果。
Copy[SC] CreateService SUCCESS
然后我们要做的就是启动服务。
Copysc start TestService
现在我们可以查看一下我们的日志文件,查看服务的运行情况。
如果想要停止并删除服务,我们可以使用一下命令。
Copysc stop TestService
sc delete TestService
服务调试#
在这里,我真的认为,使用"Microsoft"的方式注定会失败。因为调试服务实在是太繁琐了。
首先,我们将ServiceBase
中重写的方法设置为受保护,这意味着我们无法在类之外访问它们,这使得调试它们变得更加困难。这里我发现最好的方法是为每个事件提供一个public方法, 并在受保护方法中调用这些public方法来完成功能,这虽然有点混乱,
Copypublic void OnStartPublic(string[] args)
{
Log("Starting");
} protected override void OnStart(string[] args)
{
OnStartPublic(args);
base.OnStart(args);
}
但是至少我们可以做如下了事情了。
Copystatic void Main(string[] args)
{
var loggingService = new LoggingService();
if (true) //Some check to see if we are in debug mode (Either #IF Debug etc or an app setting)
{
loggingService.OnStartPublic(new string[0]);
while(true)
{
//Just spin wait here.
Thread.Sleep(1000);
}
//Call stop here etc.
}
else
{
ServiceBase.Run(new LoggingService());
}
}
你的另一个选择是,在调试模式下进行项目发布,安装服务,然后附加调试器。实际上,这是Microsoft建议你使用的方式,但是我认为这简直一团糟。
后续#
实际上,我们可以在这里做一些其他非常有用的事情, 比如我们可以通过创建一个install.bat批处理文件来为我们运行SC Create命令。但我认为,上面我们看到的调试问题,已经让我不再想使用这种方式了。 幸运的是,有一个名为Topshelf
的库可以帮助我们减轻很多麻烦,在本系列的下一部分中,我们将研究如何它。
使用.NET Core创建Windows服务(一) - 使用官方推荐方式的更多相关文章
- 使用.NET Core创建Windows服务(二) - 使用Topshelf方式
原文:Creating Windows Services In .NET Core – Part 2 – The "Topshelf" Way 作者:Dotnet Core Tut ...
- 使用.NET Core创建Windows服务 - 使用.NET Core工作器方式
原文:Creating Windows Services In .NET Core – Part 3 – The ".NET Core Worker" Way 作者:Dotnet ...
- .NET Core 创建Windows服务
.NET Core 创建Windows服务 作者:高堂 原文地址:https://www.cnblogs.com/gaotang/p/10850564.html 写在前面 使用 TopShelf+Au ...
- 使用.NET Core创建Windows服务详细步骤
目录 #创建步骤 1.使用Visual Studio创建 2.使用命令行创建 #项目结构说明 #将应用转换成Window服务 1.引入Microsoft.Extensions.Hosting.Wind ...
- 使用.NET Core中创建Windows服务(一) - 使用官方推荐方式
原文:Creating Windows Services In .NET Core – Part 1 – The "Microsoft" Way 作者:Dotnet Core Tu ...
- 使用.Net Core 2.2创建windows服务
使用.Net Core 2.2创建windows服务 我的环境 win 10 home Visual Studio 2019 v16.1.3 安装有.net core 2.2 创建项目 编辑项目文件 ...
- C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- 用C#创建Windows服务(Windows Services)
用C#创建Windows服务(Windows Services) 学习: 第一步:创建服务框架 创建一个新的 Windows 服务项目,可以从Visual C# 工程中选取 Windows 服务(W ...
- 玩转Windows服务系列——创建Windows服务
创建Windows服务的项目 新建项目->C++语言->ATL->ATL项目->服务(EXE) 这样就创建了一个Windows服务项目. 生成的解决方案包含两个项目:Servi ...
随机推荐
- SCOI2009迷路
当初学矩阵幂的时候弃掉了,那时候只会用矩阵优化递推,碰到这种图论的瞬间躺地. 昨天听学长的课,有一道例题,在边权为一的图上求从某点到某点的路径方案数,只要对邻接矩阵跑qpow就完事了. 于是自己画了个 ...
- IDEA下载安装及绿色方法
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 2018-2019-2 20165215《网络对抗技术》Exp10 Final Windows本地内核提权+Exploit-Exercises Nebula学习与实践
目录 PART ONE :Windows本地内核提权 漏洞概述 漏洞原理 漏洞复现 windbg调试本地内核 查看SSDT表和SSDTShadow表 查看窗口站结构体信息 利用Poc验证漏洞 漏洞利用 ...
- 【Blog怎么玩】什么叫EntryName友好地址名?
EntryName友好地址名 其实就是你这个页面的别名,如果设置的好的话,在SEO搜索中,会更清晰的显示出来. 好处1:清晰的URL 比如我有一篇展示可爱兔子的博文,我想让它的网址清晰的显示出来,而不 ...
- koa 基础(五)动态路由的传值
1.动态路由的传值 app.js /** * 动态路由的传值 */ // 引入模块 const Koa = require('koa'); const router = require('koa-ro ...
- Win10 的微软输入法输入稍快竟然会导致死机
一周前,新装机器一次,竟然死机两三次,多发生在敲字时,最近逐步排查发现的这个问题,查阅了一下网上方案,果断采用了第三方输入法,至今没再死机过. 不过第三方输入法也不安分,是不是推送点头条新闻过来,和驱 ...
- layui 表单遇到的小问题
select中的option 居中显示 /*select显示的option居中*/ /*.layui-select-title input{ text-align: center; }*/ /*opt ...
- mysql之备份与恢复
数据备份全备 备份命令 :mysqldump把数据库的数据以sql语句导出属于逻辑备份 格式 : mysqldump -uroot -p123456 -S 多实例的mysql.sock 数据库名 &g ...
- 【巨坑】springmvc 输出json格式数据的几种方式!
最近公司项目需要发布一些数据服务,从设计到实现两天就弄完了,心中窃喜之. 结果临近部署时突然发现..... 服务输出的JSON 数据中 date 类型数据输出格式要么是时间戳,要么是 {&quo ...
- Ubuntu16.04中安装VirtualBox及简单配置
sudo apt-get -y install virtualbox 注:将该图表拖到桌面上即可 往下的过程都不变..... 将左边的菜单栏移动到下面 打开一个终端输入:gsettings set c ...