更新前要执行的命令。解压缩后,在解压缩目录执行

This commit is contained in:
智能大石头 2023-01-01 23:54:18 +08:00
parent effb7a397b
commit ca67633405
8 changed files with 119 additions and 56 deletions

View File

@ -405,49 +405,64 @@ internal class MyService : ServiceBase, IServiceProvider
}
else
{
client.WriteInfoEvent("Upgrade", "下载完成,准备覆盖文件");
// 执行更新,解压缩覆盖文件
var rs = ug.Update();
if (rs && !ur.Executor.IsNullOrEmpty()) ug.Run(ur.Executor);
_lastVersion = ur.Version;
// 去除多余入口文件
ug.Trim("StarAgent");
// 强制更新时,马上重启
if (rs && ur.Force)
client.WriteInfoEvent("Upgrade", "下载完成,准备解压文件");
if (!ug.Extract())
{
// 带有-s参数就算是服务中运行
var inService = "-s".EqualIgnoreCase(Environment.GetCommandLineArgs());
// 以服务方式运行时,重启服务,否则采取拉起进程的方式
if (inService || Host is Host host && host.InService)
client.WriteInfoEvent("Upgrade", "解压失败");
}
else
{
if (!ur.Preinstall.IsNullOrEmpty())
{
//rs = Host.Restart("StarAgent");
// 使用外部命令重启服务
rs = ug.Run("StarAgent", "-restart -upgrade");
client.WriteInfoEvent("Upgrade", "执行预安装脚本");
client.WriteInfoEvent("Upgrade", "强制更新完成,准备重启后台服务");
//!! 这里不需要自杀,外部命令重启服务会结束当前进程
ug.Run(ur.Preinstall);
}
else
client.WriteInfoEvent("Upgrade", "解压完成,准备覆盖文件");
// 执行更新,解压缩覆盖文件
var rs = ug.Update();
if (rs && !ur.Executor.IsNullOrEmpty()) ug.Run(ur.Executor);
_lastVersion = ur.Version;
// 去除多余入口文件
ug.Trim("StarAgent");
// 强制更新时,马上重启
if (rs && ur.Force)
{
// 重新拉起进程
rs = ug.Run("StarAgent", "-run -upgrade");
// 带有-s参数就算是服务中运行
var inService = "-s".EqualIgnoreCase(Environment.GetCommandLineArgs());
if (rs)
// 以服务方式运行时,重启服务,否则采取拉起进程的方式
if (inService || Host is Host host && host.InService)
{
StopWork("Upgrade");
//rs = Host.Restart("StarAgent");
// 使用外部命令重启服务
rs = ug.Run("StarAgent", "-restart -upgrade");
client.WriteInfoEvent("Upgrade", "强制更新完成,新进程已拉起,准备退出当前进程");
client.WriteInfoEvent("Upgrade", "强制更新完成,准备重启后台服务");
ug.KillSelf();
//!! 这里不需要自杀,外部命令重启服务会结束当前进程
}
else
{
client.WriteInfoEvent("Upgrade", "强制更新完成,但拉起新进程失败");
// 重新拉起进程
rs = ug.Run("StarAgent", "-run -upgrade");
if (rs)
{
StopWork("Upgrade");
client.WriteInfoEvent("Upgrade", "强制更新完成,新进程已拉起,准备退出当前进程");
ug.KillSelf();
}
else
{
client.WriteInfoEvent("Upgrade", "强制更新完成,但拉起新进程失败");
}
}
}
}

View File

@ -174,6 +174,7 @@
<Column Name="Strategy" DataType="String" Length="500" Description="策略。升级策略node=abcd;version=1.0,1.1;runtime=5.0.*;framework=5.*;os=*Linux*;arch=Arm;province=31*;city=4509*" />
<Column Name="Source" DataType="String" ItemType="file" Length="200" Description="升级源" />
<Column Name="FileHash" DataType="String" Description="文件哈希。MD5散列" />
<Column Name="Preinstall" DataType="String" Length="200" Description="预安装命令。更新前要执行的命令,解压缩后,在解压缩目录执行" />
<Column Name="Executor" DataType="String" Length="200" Description="执行命令。空格前后为文件名和参数" />
<Column Name="CreateUserID" DataType="Int32" Description="创建者" Category="扩展" />
<Column Name="CreateTime" DataType="DateTime" Description="创建时间" Category="扩展" />

View File

@ -1613,6 +1613,17 @@
<td>MD5散列</td>
</tr>
<tr>
<td>Preinstall</td>
<td>预安装命令</td>
<td>String</td>
<td>200</td>
<td></td>
<td></td>
<td></td>
<td>更新前要执行的命令,解压缩后,在解压缩目录执行</td>
</tr>
<tr>
<td>Executor</td>
<td>执行命令</td>

View File

@ -83,6 +83,14 @@ namespace Stardust.Data.Nodes
[BindColumn("FileHash", "文件哈希。MD5散列", "")]
public String FileHash { get => _FileHash; set { if (OnPropertyChanging("FileHash", value)) { _FileHash = value; OnPropertyChanged("FileHash"); } } }
private String _Preinstall;
/// <summary>预安装命令。更新前要执行的命令,解压缩后,在解压缩目录执行</summary>
[DisplayName("预安装命令")]
[Description("预安装命令。更新前要执行的命令,解压缩后,在解压缩目录执行")]
[DataObjectField(false, false, true, 200)]
[BindColumn("Preinstall", "预安装命令。更新前要执行的命令,解压缩后,在解压缩目录执行", "")]
public String Preinstall { get => _Preinstall; set { if (OnPropertyChanging("Preinstall", value)) { _Preinstall = value; OnPropertyChanged("Preinstall"); } } }
private String _Executor;
/// <summary>执行命令。空格前后为文件名和参数</summary>
[DisplayName("执行命令")]
@ -173,6 +181,7 @@ namespace Stardust.Data.Nodes
case "Strategy": return _Strategy;
case "Source": return _Source;
case "FileHash": return _FileHash;
case "Preinstall": return _Preinstall;
case "Executor": return _Executor;
case "CreateUserID": return _CreateUserID;
case "CreateTime": return _CreateTime;
@ -196,6 +205,7 @@ namespace Stardust.Data.Nodes
case "Strategy": _Strategy = Convert.ToString(value); break;
case "Source": _Source = Convert.ToString(value); break;
case "FileHash": _FileHash = Convert.ToString(value); break;
case "Preinstall": _Preinstall = Convert.ToString(value); break;
case "Executor": _Executor = Convert.ToString(value); break;
case "CreateUserID": _CreateUserID = value.ToInt(); break;
case "CreateTime": _CreateTime = value.ToDateTime(); break;
@ -238,6 +248,9 @@ namespace Stardust.Data.Nodes
/// <summary>文件哈希。MD5散列</summary>
public static readonly Field FileHash = FindByName("FileHash");
/// <summary>预安装命令。更新前要执行的命令,解压缩后,在解压缩目录执行</summary>
public static readonly Field Preinstall = FindByName("Preinstall");
/// <summary>执行命令。空格前后为文件名和参数</summary>
public static readonly Field Executor = FindByName("Executor");
@ -292,6 +305,9 @@ namespace Stardust.Data.Nodes
/// <summary>文件哈希。MD5散列</summary>
public const String FileHash = "FileHash";
/// <summary>预安装命令。更新前要执行的命令,解压缩后,在解压缩目录执行</summary>
public const String Preinstall = "Preinstall";
/// <summary>执行命令。空格前后为文件名和参数</summary>
public const String Executor = "Executor";

View File

@ -141,6 +141,7 @@ public class NodeController : BaseController
Version = pv.Version,
Source = url,
FileHash = pv.FileHash,
Preinstall = pv.Preinstall,
Executor = pv.Executor,
Force = pv.Force,
Description = pv.Description,

View File

@ -192,6 +192,7 @@ public class LocalStarClient
var client = new HttpClient();
client.DownloadFileAsync(url, ug.SourceFile).Wait();
ug.Extract();
ug.Update();
File.Delete(ug.SourceFile);

View File

@ -1,26 +1,28 @@
using System;
namespace Stardust.Models
namespace Stardust.Models;
/// <summary>更新响应</summary>
public class UpgradeInfo
{
/// <summary>更新响应</summary>
public class UpgradeInfo
{
/// <summary>版本号</summary>
public String Version { get; set; }
/// <summary>版本号</summary>
public String Version { get; set; }
/// <summary>更新源Url地址</summary>
public String Source { get; set; }
/// <summary>更新源Url地址</summary>
public String Source { get; set; }
/// <summary>文件哈希</summary>
public String FileHash { get; set; }
/// <summary>文件哈希</summary>
public String FileHash { get; set; }
/// <summary>更新后要执行的命令</summary>
public String Executor { get; set; }
/// <summary>更新前要执行的命令。解压缩后,在解压缩目录执行</summary>
public String Preinstall { get; set; }
/// <summary>是否强制更新,覆盖文件后即刻重启应用,不需要用户同意</summary>
public Boolean Force { get; set; }
/// <summary>更新后要执行的命令</summary>
public String Executor { get; set; }
/// <summary>描述</summary>
public String Description { get; set; }
}
/// <summary>是否强制更新,覆盖文件后即刻重启应用,不需要用户同意</summary>
public Boolean Force { get; set; }
/// <summary>描述</summary>
public String Description { get; set; }
}

View File

@ -26,6 +26,9 @@ public class Upgrade
/// <summary>更新源文件</summary>
public String SourceFile { get; set; }
/// <summary>解压缩的临时目录</summary>
public String TempPath { get; set; }
#endregion
#region
@ -86,14 +89,10 @@ public class Upgrade
return md5.EqualIgnoreCase(hash);
}
/// <summary>检查并执行更新操作</summary>
public virtual Boolean Update()
/// <summary>解压缩</summary>
/// <returns></returns>
public virtual Boolean Extract()
{
var dest = DestinationPath;
// 删除备份文件
DeleteBackup(dest);
var file = SourceFile;
if (!File.Exists(file)) return false;
@ -102,10 +101,27 @@ public class Upgrade
// 解压更新程序包
if (!file.EndsWithIgnoreCase(".zip")) return false;
var tmp = Path.GetTempPath().CombinePath(Path.GetFileNameWithoutExtension(file));
var tmp = TempPath;
if (tmp.IsNullOrEmpty()) tmp = TempPath = Path.GetTempPath().CombinePath(Path.GetFileNameWithoutExtension(file));
WriteLog("解压缩到临时目录 {0}", tmp);
file.AsFile().Extract(tmp, true);
return true;
}
/// <summary>执行更新,拷贝文件</summary>
public virtual Boolean Update()
{
var dest = DestinationPath;
// 删除备份文件
DeleteBackup(dest);
var tmp = TempPath;
if (!Directory.Exists(tmp)) return false;
WriteLog("发现更新源目录 {0}", tmp);
// 记录移动文件,更新失败时恢复
var dic = new Dictionary<String, String>();
try