支持本地接口安装与卸载服务

This commit is contained in:
大石头 2022-05-30 20:01:20 +08:00
parent 4e7241cbe6
commit aab31b57f1
8 changed files with 182 additions and 28 deletions

View File

@ -205,7 +205,7 @@ namespace StarAgent
Service = this,
Host = Host,
Manager = _Manager,
PluginManager = _PluginManager,
//PluginManager = _PluginManager,
StarSetting = StarSetting,
AgentSetting = AgentSetting,
Log = XTrace.Log

View File

@ -32,8 +32,8 @@ namespace StarAgent
/// <summary>应用服务管理</summary>
public ServiceManager Manager { get; set; }
/// <summary>插件管理</summary>
public PluginManager PluginManager { get; set; }
///// <summary>插件管理</summary>
//public PluginManager PluginManager { get; set; }
/// <summary>星尘设置</summary>
public StarSetting StarSetting { get; set; }
@ -48,7 +48,7 @@ namespace StarAgent
[Api(nameof(Info))]
public AgentInfo Info(AgentInfo info)
{
XTrace.WriteLine(info.ToJson());
XTrace.WriteLine("Info<={0}", info.ToJson());
var set = StarSetting;
// 使用对方送过来的星尘服务端地址
@ -77,6 +77,11 @@ namespace StarAgent
return ai;
}
void CheckLocal()
{
if (Session is INetSession ns && !ns.Remote.Address.IsLocal()) throw new InvalidOperationException("禁止非本机操作!");
}
/// <summary>杀死并启动进程</summary>
/// <param name="processId">进程</param>
/// <param name="delay">延迟结束的秒数</param>
@ -87,7 +92,7 @@ namespace StarAgent
[Api(nameof(KillAndStart))]
public Object KillAndStart(Int32 processId, Int32 delay, String fileName, String arguments, String workingDirectory)
{
if (Session is INetSession ns && !ns.Remote.Address.IsLocal()) throw new InvalidOperationException("禁止非本机操作!");
CheckLocal();
var p = Process.GetProcessById(processId);
if (p == null) throw new InvalidOperationException($"无效进程Id[{processId}]");
@ -139,6 +144,48 @@ namespace StarAgent
return new { name, pid };
}
/// <summary>安装应用服务(星尘代理守护)</summary>
/// <param name="service"></param>
/// <returns></returns>
[Api(nameof(Install))]
public ProcessInfo Install(ServiceInfo service)
{
XTrace.WriteLine("Install<={0}", service.ToJson());
CheckLocal();
var rs = Manager.Install(service);
if (rs != null)
{
var set = Setting.Current;
set.Services = Manager.Services;
set.Save();
}
return rs;
}
/// <summary>卸载应用服务</summary>
/// <param name="serviceName"></param>
/// <returns></returns>
[Api(nameof(Uninstall))]
public Boolean Uninstall(String serviceName)
{
XTrace.WriteLine("Uninstall<={0}", serviceName);
CheckLocal();
var rs = Manager.Uninstall(serviceName, "ServiceUninstall");
if (rs)
{
var set = Setting.Current;
set.Services = Manager.Services;
set.Save();
}
return rs;
}
#endregion
#region

View File

@ -8,6 +8,7 @@ using NewLife.Log;
using NewLife.Messaging;
using NewLife.Net;
using NewLife.Remoting;
using Stardust.Managers;
using Stardust.Models;
namespace Stardust
@ -55,9 +56,7 @@ namespace Stardust
public AgentInfo GetInfo()
{
var task = GetInfoAsync().ContinueWith(t => t.IsCompleted ? t.Result : null);
if (task.Wait(500)) return task.Result;
return null;
return task.Wait(500) ? task.Result : null;
}
/// <summary>获取信息</summary>
@ -329,6 +328,50 @@ namespace Stardust
}
#endregion
#region
/// <summary>安装应用服务(星尘代理守护)</summary>
/// <param name="service"></param>
/// <returns></returns>
public async Task<ProcessInfo> Install(ServiceInfo service)
{
Init();
return await _client.InvokeAsync<ProcessInfo>("Install", service);
}
/// <summary>安装应用服务(星尘代理守护)</summary>
/// <param name="name">服务名,唯一标识</param>
/// <param name="fileName">文件</param>
/// <param name="arguments">参数</param>
/// <param name="workingDirectory">工作目录</param>
/// <returns></returns>
public async Task<ProcessInfo> Install(String name, String fileName, String arguments = null, String workingDirectory = null)
{
Init();
return await _client.InvokeAsync<ProcessInfo>("Install", new ServiceInfo
{
Name = name,
FileName = fileName,
Arguments = arguments,
WorkingDirectory = workingDirectory,
AutoStart = true,
ReloadOnChange = true,
});
}
/// <summary>卸载应用服务</summary>
/// <param name="serviceName"></param>
/// <returns></returns>
public async Task<Boolean> Uninstall(String serviceName)
{
Init();
return await _client.InvokeAsync<Boolean>("Uninstall", serviceName);
}
#endregion
#region
/// <summary>在局域网中广播扫描所有StarAgent</summary>
/// <param name="local">本地信息,用于告知对方我是谁</param>

View File

@ -1,18 +1,20 @@
using System.Diagnostics;
using NewLife.IO;
namespace Stardust.Managers;
namespace Stardust.Managers;
/// <summary>服务运行信息</summary>
internal class ProcessInfo
public class ProcessInfo
{
/// <summary>名称</summary>
public String Name { get; set; }
/// <summary>进程Id</summary>
public Int32 ProcessId { get; set; }
/// <summary>进程名</summary>
public String ProcessName { get; set; }
/// <summary>创建时间</summary>
public DateTime CreateTime { get; set; }
/// <summary>更新时间</summary>
public DateTime UpdateTime { get; set; }
}

View File

@ -194,6 +194,20 @@ internal class ServiceController : DisposeBase
}
}
/// <summary>获取进程信息</summary>
/// <returns></returns>
public ProcessInfo ToModel()
{
return new ProcessInfo
{
Name = Name,
ProcessId = ProcessId,
ProcessName = ProcessName,
CreateTime = StartTime,
UpdateTime = DateTime.Now,
};
}
private void StartMonitor()
{
// 定时检查文件是否有改变

View File

@ -43,14 +43,24 @@ namespace Stardust.Managers
#endregion
#region
/// <summary>添加应用服务</summary>
/// <summary>添加应用服务,或替换同名服务</summary>
/// <param name="services">应用服务集合</param>
public void Add(ServiceInfo[] services)
public void Add(params ServiceInfo[] services)
{
var list = Services.ToList();
foreach (var item in services)
{
if (!list.Any(e => e.Name.EqualIgnoreCase(item.Name))) list.Add(item);
//if (!list.Any(e => e.Name.EqualIgnoreCase(item.Name))) list.Add(item);
var flag = false;
for (var i = 0; i < list.Count; i++)
{
if (list[i].Name.EqualIgnoreCase(item.Name))
{
list[i] = item;
flag = true;
}
}
if (!flag) list.Add(item);
}
Services = list.ToArray();
@ -106,16 +116,9 @@ namespace Stardust.Managers
}
/// <summary>保存应用状态到数据库</summary>
void SaveDb()
private void SaveDb()
{
var list = _services.Select(e => new ProcessInfo
{
Name = e.Name,
ProcessId = e.ProcessId,
ProcessName = e.ProcessName,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now,
}).ToList();
var list = _services.Select(e => e.ToModel()).ToList();
if (list.Count == 0)
_db.Clear();
@ -159,6 +162,10 @@ namespace Stardust.Managers
return false;
}
/// <summary>停止服务</summary>
/// <param name="service"></param>
/// <param name="reason"></param>
/// <returns></returns>
private Boolean StopService(ServiceInfo service, String reason)
{
var svc = _services.FirstOrDefault(e => e.Name.EqualIgnoreCase(service.Name));
@ -204,6 +211,38 @@ namespace Stardust.Managers
}
#endregion
#region
/// <summary>安装服务,添加后启动</summary>
/// <param name="service"></param>
/// <returns></returns>
public ProcessInfo Install(ServiceInfo service)
{
Add(service);
if (!StartService(service)) return null;
SaveDb();
return _services.FirstOrDefault(e => e.Name.EqualIgnoreCase(service.Name))?.ToModel();
}
/// <summary>卸载服务</summary>
/// <param name="name"></param>
/// <param name="reason"></param>
/// <returns></returns>
public Boolean Uninstall(String name, String reason)
{
var svc = Services.FirstOrDefault(e => e.Name.EqualIgnoreCase(name));
if (svc == null) return false;
StopService(svc, reason);
SaveDb();
return true;
}
#endregion
#region
/// <summary>关联订阅事件</summary>
/// <param name="client"></param>

View File

@ -94,6 +94,8 @@ namespace Stardust
private void Init()
{
XTrace.WriteLine("正在初始化星尘……");
Local = new LocalStarClient();
// 从环境变量读取星尘地址、应用Id、密钥方便容器化部署

View File

@ -27,7 +27,7 @@ namespace Test
{
XTrace.UseConsole();
Test1();
Test6();
Console.WriteLine("OK!");
Console.ReadKey();
@ -140,11 +140,18 @@ namespace Test
XTrace.WriteLine("Test6");
var client = new LocalStarClient();
client.GetInfo();
//client.GetInfo();
try
{
await client.GetInfoAsync();
//await client.GetInfoAsync();
var rs = await client.Install("test666", "ping", "qq.com");
XTrace.WriteLine("Install={0}", rs.ToJson(true));
Thread.Sleep(3000);
var rs2 = await client.Uninstall("test666");
XTrace.WriteLine("Uninstall={0}", rs2);
}
catch (Exception ex)
{