netcore一鍵nssm發布為windows服務


AntDeploy

是我開發一款開源一鍵部署工具包

發布功能支持:

  • docker容器一鍵部署
  • docker鏡像一鍵發布
  • 支持iis一鍵部署
  • windows服務一鍵部署
  • linux服務一鍵部署
  • 支持增量發布
  • 支持一鍵回滾
  • 支持點火
  • 支持選擇特定文件發布
  • 支持查看發布記錄

一個issue

前兩天有一個使用者給我反饋了一個issue

image

他是用asp5.0開發了一個web程序,然后用AntDeploy來部署,
由於AntDeploy部署時讀取服務的安裝路徑,然后進行更新。
但是針對nssm部署的服務有一個特點,執行路徑是nssm.exe,如下圖:

image

那么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. 根據真實路徑進行部署

image

既然是開源軟件,就讓這位仁兄來幫我寫這部分代碼吧

image

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

image

image

開源就是要參與進來 這也是我熱愛開源的原因

擴展nssm發布windows功能

上面雖然已經解決了:首次用nssm發布,后面用AntDeploy來更新的場景。

還需要解決掉首次無法使用nssm發布的功能。

我覺得有必要加這個功能,來完成nssm發布windows服務的閉環

好處有:

一般按照微軟開發winfows服務的標准的話 是需要引入包:Microsoft.Extensions.Hosting.WindowsServices

但是用nssm可以不需要引入。

所以在netcore開發web的場景使用nssm安裝為windows服務很方便

而且使用nssm安裝的另外一個優點是可以指定啟動參數? 比如 --urls=http://*:10007

開始開發

1. 客戶端 增加入口可以使用nssm

image

2. ageng端增加 nssm

在windows場景下才 作為內嵌資源。針對linux場景不需要。

image

在啟動的時候釋放出來:


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;
    }
    catch (Exception ex)
    {
        return false;
    }
    finally
    {
        process?.Dispose();
    }
}

以aspnet5的web測試
完整的運行效果是:

image

服務部署成功

image

訪問成功

image

成功物

插件最新版: v7.32

agent最新版:v6.9

源碼地址:https://github.com/yuzd/AntDeployAgent

交流QQ群:488312978


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM