netcore一键nssm发布为windows服务
AntDeploy
是我开发一款开源一键部署工具包
发布功能支持:
- docker容器一键部署
- docker镜像一键发布
- 支持iis一键部署
- windows服务一键部署
- linux服务一键部署
- 支持增量发布
- 支持一键回滚
- 支持点火
- 支持选择特定文件发布
- 支持查看发布记录
一个issue
前两天有一个使用者给我反馈了一个issue
他是用asp5.0开发了一个web程序,然后用AntDeploy来部署,
由于AntDeploy部署时读取服务的安装路径,然后进行更新。
但是针对nssm部署的服务有一个特点,执行路径是nssm.exe,如下图:
那么AntDeploy在更新部署的时候会更新到nssm.exe所在的目录了。
解决思路
nssm是一个开源c语言写的软件,大概只有300kb,可以很方便的把程序安装成一个windows服务。
nssm就像是一个服务管理器,windows服务启动的时候 会调用nssm.exe传入serviceName、然后nssm.exe会根据serviceName拿到配置的实际要运行的文件。
查了下nssm官网
可以根据命令
nssm get <serviceName> Application
获取实际要执行的程序地址
那么要想要兼容第一次是由nssm.exe部署,后面用AntDeploy发布的场景,则需要
-
-
根据调用nssm的命令拿到真实路径
-
-
根据真实路径进行部署
既然是开源软件,就让这位仁兄来帮我写这部分代码吧
果然这位仁兄战斗力可以,很快就搞定了
开源就是要参与进来 这也是我热爱开源的原因
扩展nssm发布windows功能
上面虽然已经解决了:首次用nssm发布,后面用AntDeploy来更新的场景。
还需要解决掉首次无法使用nssm发布的功能。
我觉得有必要加这个功能,来完成nssm发布windows服务的闭环
好处有:
一般按照微软开发winfows服务的标准的话 是需要引入包:Microsoft.Extensions.Hosting.WindowsServices 但是用nssm可以不需要引入。 所以在netcore开发web的场景使用nssm安装为windows服务很方便 而且使用nssm安装的另外一个优点是可以指定启动参数? 比如 --urls=http://*:10007
开始开发
1. 客户端 增加入口可以使用nssm
2. ageng端增加 nssm
在windows场景下才 作为内嵌资源。针对linux场景不需要。
ad8
在启动的时候释放出来:
var nssmSavePath = Path.Combine(Startup.RootPath, "nssm.exe"); if (File.Exists(nssmSavePath)) { return; } Assembly assembly = typeof(AntDeployAgentWindowsService).Assembly; using (Stream stream = assembly.GetManifestResourceStream("AntDeployAgentService.nssm.exe")) { if (stream != null) { using (var fileStream = File.Create(nssmSavePath)) { stream.Seek(0, SeekOrigin.Begin); stream.CopyTo(fileStream); } } } if (!File.Exists(nssmSavePath)) { throw new FileNotFoundException(nssmSavePath + " not found"); }
和客户端约定了2个新传参:
- useNssm 客户端是否选择采用nssm来部署服务
- param 服务运行的参数
agent端处理第一次用nssm部署
主要用到了下面几个命令:
nssm install <serviceName> "<实际执行文件的完整路径>" nssm set <serviceName> AppDirectory "<实际执行文件所在的目录>" nssm set <serviceName> Description "<服务的描述>" nssm set <serviceName> AppParameters "<服务运行指定的参数>" nssm start <serviceName>
封装一个方法来执行nssm命令
public static bool RunExternalExe(string projectPath, string arguments, Action<string> logger) { Process process = null; try { if (string.IsNullOrEmpty(arguments)) { throw new ArgumentException(nameof(arguments)); } process = new Process(); process.StartInfo.FileName = projectPath; process.StartInfo.Arguments = arguments; process.StartInfo.CreateNoWindow = true; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.StartInfo.UseShellExecute = false; process.StartInfo.Verb = "runas"; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.Start(); process.OutputDataReceived += (sender, args) => { if (!string.IsNullOrWhiteSpace(args.Data)) { logger(args.Data); } }; process.BeginOutputReadLine(); process.ErrorDataReceived += (sender, data) => { if (!string.IsNullOrWhiteSpace(data.Data)) logger(data.Data); }; process.BeginErrorReadLine(); process.WaitForExit(); //var err = process.StandardError.ReadToEnd(); return process.ExitCode == 0 ad1 ; } catch (Exception ex) { return false; } finally { process?.Dispose(); } }
以aspnet5的web测试
完整的运行效果是:
服务部署成功
访问成功
成功物
插件最新版: v7.32
agent最新版:v6.9
源码地址:https://github.com/yuzd/AntDeployAgent
交流QQ群:488312978
- netcore一键制作镜像并发布到腾讯云镜像仓库
- netcore开发windows普通服务(非Web)并一键发布到服务器
- DotNetCore跨平台~2.0提前发布喽
- 发布时一键添加html中的css标签和script标签版本号来防止浏览器缓存
- LNMP一键安装包 0.6 正式发布
- jenkins+maven+svn实现简单的一键发布
- docker发布netcore网站-零散记录
- 微软发布新工具:一键搞定VSCode的Java开发环境
- 阿里云发布ECS磁盘加密,一键加密,业务0改动
- shopex采集发布接口 shopex火车头数据采集器(20120812更新) 使用火车头接口技术一键批量采集 批量发布 批量去水印 接口技术
- jenkins+maven+svn实现简单的一键发布
- Jenkins一键发布「apk&ipa」 到Bugly
- 酷传一键应用发布 : http://publish.kuchuan.com/myaccount/accounts
- .netcoreapp 发布到 linux 的问题,vs靠不住
- 用Python3、NetCore、Shell分别开发一个Ubuntu版的定时提醒(附NetCore跨平台两种发布方式)
- [AHK]为编辑器开发gist插件,实现一键发布脚本到gist
- WCF开发实战系列四:使用Windows服务发布WCF服务
- 一键发布多个端口tomcat,重启脚本等
- 【百度贴吧】一键回复插件发布!
- Jenkins+SVN+Maven+Shell 实现项目一键发布