日常工作中有时候会遇到需要将程序直接在服务器上运行,而不依赖于 iis 托管的情况,直接运行有两种方式,一种是部署为 服务模式,另一种则是 直接启动 .net 发布之后的 exe 文件以 控制台模式运行,控制台模式运行主要问题是服务器在重新启动之后不会自动启动,当然也可以选择配置 windows 计划任务的形式让 控制台在服务器开机时自动启动, 今天给大家分享 .net 控制台程序和 .net 开发的 webapi 及 web 项目在以 windows 服务模式部署时的一些注意事项。
.net 项目想要部署为 windows 服务,首先需要通过 nuget 安装 microsoft.extensions.hosting.windowsservices ,然后在程序启动时做如下配置:
控制台程序:
using common;namespace taskservice {class program {static void main(string[] args) { environmenthelper.changedirectory(args); ihost host = host.createdefaultbuilder(args).usewindowsservice() .configureservices((hostcontext, services) =>{///各种服务注入 }) .build(); host.run(); } } }
web 及 webapi 程序:
using common;namespace webapi {public class program {public static void main(string[] args) { environmenthelper.changedirectory(args);var builder = webapplication.createbuilder(args); builder.host.usewindowsservice();//各种服务注入var app = builder.build(); app.run(); } } }
以上是两种常见程序的启动 main 函数的配置 windows 托管模式的演示,其中一个关键点在于 environmenthelper.changedirectory(args);
该方法用于在服务启动时将运行路径重新指向为程序所在目录,默认情况下 .net 程序在命令启动时,运行路径为执行命令的路径比如在 cmd 中执行如下命令:
虽然程序是放在 d:\publish\ 文件夹中,但是因为我们执行启动程序命令时的路径是在 c:\user\zhangxiaodong 所以程序启动之后的运行环境路径就是 命令执行当前目录,c:\user\zhangxiaodong 这时候如果我们的代码中有包含一些涉及到操作 程序所在目录的 io 操作时就会产生异常,比如 加载 web 项目下的 wwwroot 文件夹中的静态资源,这些都会异常,所以我们需要在程序启动时将 运行目录重定向到 我们的程序所在目录,就用到了 environmenthelper.changedirectory(args); 这个方法。
environmenthelper.changedirectory(args); 实现如下:
using microsoft.extensions.configuration.commandline;namespace common {////// 环境操作helper方法/// public class environmenthelper {////// 改变工作目录/// /// public static void changedirectory(string[] args) {var cmdconf = new commandlineconfigurationprovider(args); cmdconf.load();if (cmdconf.tryget("cd", out string cdstr) && bool.tryparse(cdstr, out bool cd) && cd) { directory.setcurrentdirectory(appcontext.basedirectory); } } } }
主要逻辑是判断启动命令中 cd 参数的值是否为 true ,如果 cd=true 则重新配置程序的 currentdirectory 为程序文件所在目录。
调整之后我们在启动程序时只要多添加一个参数即可,如下:
只要在原本的启动命令 dotnet d:\publish\webapi.dll 优化为 dotnet d:\publish\webapi.dll --cd='true' 即可,从上图可以看出虽然我们的启动命令还是在 c:\user\zhangxiaodong 目录执行的,但是程序的运行目录已经被重定向到了 dotnet d:\publish\ 这个路径也正是我们的程序所在路径。
有了上面的基础,我们就可以利用 windows服务器的 sc 指令来配置服务部署了,具体命令如下:
安装
sc.exe create myapi binpath= 'd:\publish\webapi.exe --cd="true"' start= auto
安装成功之后控制台会输出 [sc] createservice 成功 ,其中 myapi 时我们创建服务时指定的服务名称,binpath 即是我们的程序路径,注意 true 是 用英文状态的双引号包裹,然后整个 binpath 采用因为状态的 单引号包裹,start= auto 则表示将我们的 myapi 服务设置为自动启动。
在 windows 服务管理中也可以看到百家乐凯发k8的服务
启动命令和停止命令,和我们日常操作普通服务的命令一样都是 net start 服务名 和 net stop 服务名,如下:
启动:
net start myapi
停止
net stop myapi
卸载命令:
sc.exe delete 服务名称
如:sc.exe delete myapi
至此 .net 实现启动时重定向程序运行路径及 windows 服务运行模式部署 就讲解完了。