您的位置:首页 > 其它

netcore一键nssm发布为windows服务

2021-07-31 21:41 931 查看

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发布的场景,则需要

    1. 根据调用nssm的命令拿到真实路径
    1. 根据真实路径进行部署

既然是开源软件,就让这位仁兄来帮我写这部分代码吧

果然这位仁兄战斗力可以,很快就搞定了

开源就是要参与进来 这也是我热爱开源的原因

扩展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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: