.NET 实现启动时重定向程序运行路径及 Windows 服务运行模式部署
日常工作中有时候会遇到需要将程序直接在服务器上运行,而不依赖于 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
{ /// <summary>
/// 环境操作Helper方法
/// </summary>
public class EnvironmentHelper
{ /// <summary>
/// 改变工作目录
/// </summary>
/// <param name="args"></param>
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 服务管理中也可以看到我们的服务


启动命令和停止命令,和我们日常操作普通服务的命令一样都是 net start 服务名 和 net stop 服务名,如下:
启动:
net start MyAPI

停止
net stop MyAPI

卸载命令:
sc.exe delete 服务名称
如:sc.exe delete MyAPI

.NET 实现启动时重定向程序运行路径及 Windows 服务运行模式部署的更多相关文章
- 黄聪:使用srvany.exe将任何程序作为Windows服务运行
srvany.exe是什么? srvany.exe是Microsoft Windows Resource Kits工具集的一个实用的小工具,用于将任何EXE程序作为Windows服务运行.也就是说sr ...
- 使用srvany.exe将任何程序作为Windows服务运行
使用srvany.exe将任何程序作为Windows服务运行 2011 年 3 月 7 日 !本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使 ...
- srvany把程序作为Windows服务运行
srvany.exe是什么? srvany.exe是Microsoft Windows Resource Kits工具集的一个实用的小工具,用于将任何EXE程序作为Windows服务运行.也就是说sr ...
- .NET Worker Service 作为 Windows 服务运行及优雅退出改进
上一篇文章我们了解了如何为 Worker Service 添加 Serilog 日志记录,今天我接着介绍一下如何将 Worker Service 作为 Windows 服务运行. 我曾经在前面一篇文章 ...
- 请高手解释这个C#程序,其中ServiceBase是windows服务基类,SmsService是
请高手解释这个C#程序,其中ServiceBase是windows服务基类,SmsService是 ServiceBase的子类. static void Main() { ServiceBase[] ...
- pm2以windows服务运行
借助于pm2-windows-service 可以把pm2以windows服务运行.已服务运行的好处就是,即时用户注销也,pm2也会在后台运行 npm i pm2 -g npm i pm2-windo ...
- 把java程序作为windows服务运行
参考: https://www.jianshu.com/p/fc9e4ea61e13 https://blog.csdn.net/qq_28566071/article/details/8088250 ...
- 把应用程序exe 注册成为windows 服务的方法
由于在Windows 服务器上必须要启动一个软件,提供外网访问内网的客户端软件,但是由于每次远程服务器之后会注销当前用户,所以客户端软件就会自动退出,那么我在外网的系统就不能支持访问了. 解决方案:将 ...
- 程序自动化需要一个Windows服务
前段时间,写了一个SPC to SQL数据传输的小功能,用户不太想用手执行或有可能忘记操作.解决这个问题,Insus.NET原本是使用windows的任务管理执行的,但觉得并不太理想,因此又得写一个W ...
随机推荐
- 简单到爆——用Python在MP4和GIF间互转,我会了
写在前面的一些P话: 昨天用公众号写文章的时候,遇到个问题.我发现公众号插入视频文件太繁琐,一个很小的视频,作为视频传上去平台还要审核,播放的时候也没gif来的直接.于是想着找个工具将mp4转换成gi ...
- Java 向数组中添加元素
一般数组是不能添加元素的,因为他们在初始化时就已定好长度了,不能改变长度. 向数组中添加元素思路 第一步:把数组转化为集合 list = Arrays.asList(array); 第二步:向集合中添 ...
- android stdio开发抖音自动点赞案例
最近做了一个安卓开发自动刷抖音. 点赞. 评论等等养号行为. 总结一下知识点和遇到的一些问题: 知识点: 1. 使用acessibility mode 对抖音自动化操作. android stdio中 ...
- Tapdata Cloud 2.1.4 来啦:数据连接又上新,PolarDB MySQL、轻流开始接入,可自动标记不支持的字段类型
需求持续更新,优化一刻不停--Tapdata Cloud 2.1.4 来啦! 最新发布的版本中,在新增数据连接之余,默认标记不支持同步的字段类型,避免因此影响任务的正常运行. 更新速览 ① 数 ...
- vue Blob 下载附件报错
vue Blob 下载附件报错,不妨试试: window.location.href=后台地址
- STM32与物联网01-ESP8266基本操作
ESP8266物联网简介 ESP8266简介 ESP8266 是上海乐鑫公司开发的一款具有 WiFi 功能的控制芯片,它带有完整的 TCP/IP 协议栈,因此可以用作物联网开发. ESP8266 本身 ...
- 各大厂的语音识别Speech To Text API使用体验
最近发现有声读物能极大促进我的睡眠,但每个前面都有一段开场语,想把它剪掉,但是有多个开场语,所以就要用到语音识别判断一下再剪. 前两年在本地搭建过识别的环境,奈何识别准确率不行,只能找找API了,后面 ...
- APISpace 疫情地区校验API接口 免费好用
从2019年疫情开始爆发到现在,我们去到某个地方都会提心吊胆的,很怕一不小心就染上了这个病毒.在去到某个地方之前,我们提前查看到它的一个疫情等级,同时做好防护再出门我们心里也会有底一些.所以疫情地区校 ...
- Solution -「校内题」Xorequ
0x00 前置芝士 数位dp考试里出现的小神题?? 显然考场会选择打表找规律. 数位dp + 矩阵快速幂 0x01 题目描述 给定正整数 \(n\),现有如下方程 \(x \bigoplus 3x = ...
- 作业二、安装CentOS7.9
一.安装环境 1.VMware Workstation 16 Pro 2.CentOS7.9 二.部署系统 步骤1.进入VMware,点击创建新的虚拟机 步骤2.进入新建虚拟机向导,选择典型(推荐) ...