Windows服务重启通过

This commit is contained in:
大石头 2020-12-02 00:52:27 +08:00
parent db5d5cab2f
commit 08443440e1
4 changed files with 137 additions and 27 deletions

View File

@ -137,6 +137,8 @@ namespace StarAgent
};
svr.Register(new StarService
{
Service = this,
Host = Host,
Manager = _Manager,
Log = XTrace.Log
}, null);

View File

@ -1,11 +1,15 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using NewLife;
using NewLife.Agent;
using NewLife.Log;
using NewLife.Reflection;
using NewLife.Remoting;
using NewLife.Threading;
using Stardust;
using Stardust.Models;
namespace StarAgent
{
@ -13,11 +17,36 @@ namespace StarAgent
public class StarService
{
#region
/// <summary>服务对象</summary>
public ServiceBase Service { get; set; }
/// <summary>服务主机</summary>
public IHost Host { get; set; }
/// <summary>本地应用服务管理</summary>
public ServiceManager Manager { get; set; }
#endregion
#region
/// <summary>信息</summary>
/// <returns></returns>
[Api(nameof(Info))]
public AgentInfo Info()
{
var p = Process.GetCurrentProcess();
var asmx = AssemblyX.Entry;
var fileName = p.MainModule.FileName;
var args = Environment.CommandLine.TrimStart(Path.ChangeExtension(fileName, ".dll")).Trim();
return new AgentInfo
{
Version = asmx?.Version,
ProcessId = p.Id,
FileName = fileName,
Arguments = args,
};
}
/// <summary>杀死并启动进程</summary>
/// <param name="processId">进程</param>
/// <param name="delay">延迟结束的秒数</param>
@ -39,6 +68,13 @@ namespace StarAgent
if (delay > 0) Thread.Sleep(delay * 1000);
// 如果要杀的是自己,则重启服务
if (processId == Process.GetCurrentProcess().Id && !fileName.IsNullOrEmpty())
{
Host.Restart(Service.ServiceName);
return;
}
try
{
if (!p.HasExited)

View File

@ -4,11 +4,13 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using NewLife;
using NewLife.Http;
using NewLife.Log;
using NewLife.Net;
using NewLife.Remoting;
using Stardust.Models;
namespace Stardust
{
@ -16,6 +18,9 @@ namespace Stardust
public class LocalStarClient
{
#region
/// <summary>代理信息</summary>
public AgentInfo Info { get; private set; }
private ApiClient _client;
#endregion
@ -39,11 +44,11 @@ namespace Stardust
/// <summary>获取信息</summary>
/// <returns></returns>
public IDictionary<String, Object> GetInfo()
public AgentInfo GetInfo()
{
Init();
return _client.Invoke<Object>("Api/Info") as IDictionary<String, Object>;
return Info = _client.Invoke<AgentInfo>("Info");
}
#endregion
@ -56,14 +61,15 @@ namespace Stardust
var p = Process.GetCurrentProcess();
var fileName = p.MainModule.FileName;
var args = Environment.CommandLine.TrimStart(Path.ChangeExtension(fileName, ".dll")).Trim();
// 发起命令
var rs = _client.Invoke<String>("KillAndStart", new
{
processId = p.Id,
delay = 3,
fileName = fileName,
arguments = Environment.CommandLine,
fileName,
arguments = args,
workingDirectory = Environment.CurrentDirectory,
});
@ -94,31 +100,32 @@ namespace Stardust
}
// 尝试连接,获取版本
var ver = "";
var pid = 0;
try
{
var info = GetInfo();
// 比目标版本高,不需要安装
ver = info["Version"] + "";
if (String.Compare(ver, version) >= 0) return true;
if (String.Compare(info.Version, version) >= 0) return true;
if (info["Process"] is IDictionary<String, Object> dic) pid = dic["ProcessId"].ToInt();
if (target.IsNullOrEmpty()) target = Path.GetDirectoryName(info.FileName);
if (target.IsNullOrEmpty() && pid > 0)
{
var p = Process.GetProcessById(pid);
if (p != null) target = Path.GetDirectoryName(p.MainModule.FileName);
}
XTrace.WriteLine("StarAgent在用版本 v{0},低于目标版本 v{1}", ver, version);
XTrace.WriteLine("StarAgent在用版本 v{0},低于目标版本 v{1}", info.Version, version);
}
catch (Exception ex)
{
XTrace.WriteLine("没有探测到StarAgent{0}", ex.GetTrue().Message);
}
if (target.IsNullOrEmpty())
{
// 在进程中查找
var p = Process.GetProcesses().FirstOrDefault(e => e.ProcessName == "StarAgent");
if (p != null)
{
target = Path.GetDirectoryName(p.MainWindowTitle);
}
}
// 准备安装,甭管是否能够成功重启,先覆盖了文件再说
{
if (target.IsNullOrEmpty())
@ -148,23 +155,68 @@ namespace Stardust
{
// 在进程中查找
var p = Process.GetProcesses().FirstOrDefault(e => e.ProcessName == "StarAgent");
if (p == null && pid > 0) p = Process.GetProcessById(pid);
var info = Info;
var p = info != null && info.ProcessId > 0 ?
Process.GetProcessById(info.ProcessId) :
Process.GetProcesses().FirstOrDefault(e => e.ProcessName == "StarAgent");
// 让对方自己退出
if (info != null)
{
//_client.Invoke<String>("KillAndStart", new { processId = info.ProcessId });
_client.Invoke<String>("KillAndStart", new
{
processId = p.Id,
fileName = info.FileName,
});
Thread.Sleep(1000);
return true;
}
// 重启目标
if (p != null) p.Kill();
if (p != null)
{
try
{
if (!p.HasExited) p.Kill();
}
catch (Exception ex)
{
XTrace.WriteException(ex);
}
}
var fileName = target.CombinePath("StarAgent.exe");
var fileName = info?.FileName ?? target.CombinePath("StarAgent.exe");
if (File.Exists(fileName))
{
if (Runtime.Linux) Process.Start("chmod", $"+x {fileName}");
var si = new ProcessStartInfo(fileName, "-run")
if (Runtime.Linux)
{
WorkingDirectory = Path.GetDirectoryName(fileName),
UseShellExecute = true
};
Process.Start(si);
Process.Start("chmod", $"+x {fileName}");
var si = new ProcessStartInfo(fileName, "-run")
{
WorkingDirectory = Path.GetDirectoryName(fileName),
UseShellExecute = true
};
Process.Start(si);
}
else
{
if (info?.Arguments == "-s")
{
Process.Start(fileName, "-start");
}
else
{
var si = new ProcessStartInfo(fileName, "-run")
{
WorkingDirectory = Path.GetDirectoryName(fileName),
UseShellExecute = true
};
Process.Start(si);
}
}
}
}

View File

@ -0,0 +1,20 @@
using System;
namespace Stardust.Models
{
/// <summary>代理信息</summary>
public class AgentInfo
{
/// <summary>进程标识</summary>
public Int32 ProcessId { get; set; }
/// <summary>版本</summary>
public String Version { get; set; }
/// <summary>文件路径</summary>
public String FileName { get; set; }
/// <summary>命令参数</summary>
public String Arguments { get; set; }
}
}