新增服务管理功能及可空引用类型支持

在 `StarAgent.csproj` 中启用可空引用类型支持。
在 `StarService.cs` 中新增获取、启动、停止和重启服务的方法,增强了服务操作的健壮性。
在 `ServiceManager.cs` 中实现服务的启动和停止逻辑,并触发状态变化事件。
在 `ServicesInfo.cs` 中新增 `ServicesInfo` 和 `ServiceOperationResult` 类,以便于服务信息和操作结果的管理。
This commit is contained in:
qcjxberin 2025-06-30 12:25:37 +08:00
parent 6796272960
commit 763389dac5
4 changed files with 211 additions and 0 deletions

View File

@ -23,6 +23,7 @@
<IsPackable>False</IsPackable>
<NoWarn>1701;1702;NU5104;NETSDK1138;CS7035</NoWarn>
<ServerGarbageCollection>false</ServerGarbageCollection>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'=='net8.0'">

View File

@ -155,6 +155,143 @@ public class StarService : DisposeBase, IApi
return set.Server;
}
/// <summary>获取所有服务列表</summary>
/// <returns></returns>
[Api(nameof(GetServices))]
public ServicesInfo GetServices()
{
CheckLocal();
var list = Manager.Services;
var runningList = Manager.RunningServices;
var result = new ServicesInfo
{
Services = list?.ToArray(),
RunningServices = runningList?.ToArray()
};
return result;
}
/// <summary>启动服务</summary>
/// <param name="serviceName">服务名称</param>
/// <returns></returns>
[Api("StartService")]
public ServiceOperationResult StartService(String serviceName)
{
CheckLocal();
if (serviceName.IsNullOrEmpty())
{
return new ServiceOperationResult { Success = false, Message = "服务名称不能为空" };
}
try
{
var result = Manager?.Start(serviceName);
return new ServiceOperationResult
{
Success = result ?? false,
Message = result == true ? "服务启动成功" : "服务启动失败或服务不存在",
ServiceName = serviceName
};
}
catch (Exception ex)
{
return new ServiceOperationResult
{
Success = false,
Message = $"启动服务时发生错误: {ex.Message}",
ServiceName = serviceName
};
}
}
/// <summary>停止服务</summary>
/// <param name="serviceName">服务名称</param>
/// <returns></returns>
[Api("StopService")]
public ServiceOperationResult StopService(String serviceName)
{
CheckLocal();
if (serviceName.IsNullOrEmpty())
{
return new ServiceOperationResult { Success = false, Message = "服务名称不能为空" };
}
try
{
var result = Manager?.Stop(serviceName, "API调用停止");
return new ServiceOperationResult
{
Success = result ?? false,
Message = result == true ? "服务停止成功" : "服务停止失败或服务不存在",
ServiceName = serviceName
};
}
catch (Exception ex)
{
return new ServiceOperationResult
{
Success = false,
Message = $"停止服务时发生错误: {ex.Message}",
ServiceName = serviceName
};
}
}
/// <summary>重启服务</summary>
/// <param name="serviceName">服务名称</param>
/// <returns></returns>
[Api("RestartService")]
public ServiceOperationResult RestartService(String serviceName)
{
CheckLocal();
if (serviceName.IsNullOrEmpty())
{
return new ServiceOperationResult { Success = false, Message = "服务名称不能为空" };
}
try
{
// 先停止服务
var stopResult = Manager?.Stop(serviceName, "API调用重启");
if (stopResult != true)
{
return new ServiceOperationResult
{
Success = false,
Message = "重启失败:无法停止服务或服务不存在",
ServiceName = serviceName
};
}
// 等待一小段时间确保服务完全停止
Thread.Sleep(1000);
// 再启动服务
var startResult = Manager?.Start(serviceName);
return new ServiceOperationResult
{
Success = startResult ?? false,
Message = startResult == true ? "服务重启成功" : "重启失败:服务停止成功但启动失败",
ServiceName = serviceName
};
}
catch (Exception ex)
{
return new ServiceOperationResult
{
Success = false,
Message = $"重启服务时发生错误: {ex.Message}",
ServiceName = serviceName
};
}
}
private void DoRefreshLocal(Object state)
{
var ai = AgentInfo.GetLocal(true);

View File

@ -18,6 +18,9 @@ public class ServiceManager : DisposeBase
/// <summary>应用服务集合</summary>
public ServiceInfo[]? Services { get; private set; }
/// <summary>正在运行的应用服务信息</summary>
public ProcessInfo[] RunningServices => _controllers.Select(e => e.ToModel()).ToArray();
/// <summary>延迟时间。重启进程或服务的延迟时间默认3000ms</summary>
public Int32 Delay { get; set; } = 3000;
@ -230,6 +233,40 @@ public class ServiceManager : DisposeBase
SaveDb();
}
/// <summary>启动指定服务</summary>
/// <param name="serviceName">服务名称</param>
/// <returns>是否成功启动</returns>
public Boolean Start(String serviceName)
{
if (serviceName.IsNullOrEmpty()) return false;
var service = Services?.FirstOrDefault(e => e.Name.EqualIgnoreCase(serviceName));
if (service == null) return false;
service.Enable = true;
var result = StartService(service, null);
RaiseServiceChanged();
return result;
}
/// <summary>停止指定服务</summary>
/// <param name="serviceName">服务名称</param>
/// <param name="reason">停止原因</param>
/// <returns>是否成功停止</returns>
public Boolean Stop(String serviceName, String reason)
{
if (serviceName.IsNullOrEmpty()) return false;
var service = Services?.FirstOrDefault(e => e.Name.EqualIgnoreCase(serviceName));
if (service == null) return false;
// 禁用服务,防止自动重启
service.Enable = false;
var result = StopService(serviceName, reason);
RaiseServiceChanged();
return result;
}
/// <summary>保存应用状态到数据库</summary>
private void SaveDb()
{

View File

@ -0,0 +1,36 @@
using Stardust.Managers;
namespace Stardust.Models;
/// <summary>应用服务集合信息</summary>
public class ServicesInfo
{
/// <summary>
/// 应用服务集合
/// </summary>
public ServiceInfo[]? Services { get; set; }
/// <summary>正在运行的应用服务信息</summary>
public ProcessInfo[]? RunningServices { get; set; }
}
/// <summary>
/// 应用服务操作结果
/// </summary>
public class ServiceOperationResult
{
/// <summary>
/// 是否成功
/// </summary>
public Boolean Success { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public String? Message { get; set; }
/// <summary>
/// 服务名称
/// </summary>
public String? ServiceName { get; set; }
}