123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- using LocalDB.DBModel;
- using log4net;
- using SCADA.CommonLib;
- using SCADA.CommonLib.Data.DIL;
- using SCADA.CommonLib.Helper;
- using SCADA.CommonLib.Service;
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Threading.Tasks;
- namespace SCADA_DAQ
- {
- /// <summary>
- ///
- /// </summary>
- public class ServiceHost : IServiceHost
- {
- /// <summary>
- ///
- /// </summary>
- public IApp AppRuntime { get; set; }
- /// <summary>
- ///
- /// </summary>
- readonly ILog log = SCADA.CommonLib.LoggerHelper.Logger.CreateLogger(typeof(ServiceHost));
- /// <summary> 已经加载的服务器集合
- /// </summary>
- public ConcurrentDictionary<string, IService> ServiceCollection { get; private set; } = new ConcurrentDictionary<string, IService>();
- /// <summary> 可选服务类型
- /// </summary>
- public Dictionary<string, Type> ServiceTypes { get; private set; } = new Dictionary<string, Type>();
- /// <summary>
- ///
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="serviceName"></param>
- /// <returns></returns>
- public T GetService<T>(string serviceName) where T : IService
- {
- if (ServiceCollection.ContainsKey(serviceName))
- {
- return (T)ServiceCollection[serviceName];
- }
- return default;
- }
- /// <summary>
- ///
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
- public T GetService<T>() where T : IService
- {
- return ServiceCollection.Values.OfType<T>().FirstOrDefault();
- }
- bool isDisposed = false;
- private ServiceHost()
- {
- }
- private static ServiceHost _instance;
- /// <summary>
- ///
- /// </summary>
- public static ServiceHost Instance { get => _instance ?? (_instance = new ServiceHost()); private set { _instance = value; } }
- private ITable serviceTable { get; set; }
- /// <summary>
- ///
- /// </summary>
- /// <param name="app"></param>
- /// <returns></returns>
- public bool Start(IApp app)
- {
- AppRuntime = app;
- return Start();
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public bool Start()
- {
- try
- {
- RpcService.GetInstance().Regiseter(this);
- var serviceTasks = new List<Task>() { };
- serviceTable = AppRuntime.RuntimeInfo.LocalAppDB?.GetValueByPath("Sys_Service", true) as ITable;
- var services = DataTableHelper.DtToList<Sys_Service>(serviceTable.GetData())?.OrderBy(t => t.StartSquence_Int);
- ServiceTypes = GetPluginTypes<IService>().ToDictionary(t => t.FullName, t => t);
- if (services == null) return false;
- foreach (var item in services)
- {
- if (item.IsEnable_Bit)
- {
- var exMsg = "";
- var serviceState = "";
- var startTime = DateTime.Now;
- if (ServiceTypes.ContainsKey(item.ServiceType_Str))
- {
- var task = Task.Factory.StartNew(() =>
- {
- System.Diagnostics.Stopwatch st = null;
- try
- {
- System.Threading.Thread.Sleep(item.StartDelay_Int);
- log.Debug($"服务ID:{item.ID} ,类型:{item.ServiceType_Str} 开始启动");
- st = new System.Diagnostics.Stopwatch();
- st.Start();
- var type = ServiceTypes[item.ServiceType_Str];
- var constructorInfoArray = type.GetConstructors(BindingFlags.Instance
- | BindingFlags.NonPublic
- | BindingFlags.Public);
- ConstructorInfo noParameterConstructorInfo = null;
- foreach (ConstructorInfo constructorInfo in constructorInfoArray)
- {
- ParameterInfo[] parameterInfoArray = constructorInfo.GetParameters();
- if (0 == parameterInfoArray.Length)
- {
- noParameterConstructorInfo = constructorInfo;
- break;
- }
- }
- if (null == noParameterConstructorInfo)
- {
- throw new NotSupportedException($"Service {item.ServiceType_Str} 没有默认构造函数");
- }
- var service = (IService)noParameterConstructorInfo.Invoke(null);
- if (service.ConfigType != null)
- {
- service.ServiceConfig = (ObservableObject)JsonHelper.JsonDeserialize(item.ServiceConfig_Str, service.ConfigType) ??
- (ObservableObject)Activator.CreateInstance(service.ConfigType);
- }
- service.AppRuntime = AppRuntime;
- service.ServiceId = item.ID.ToString();
- service.ServiceName = item.ServiceName_Str;
- service.Start();
- startTime = DateTime.Now;
- serviceState = "启动成功";
- ServiceCollection.TryAdd(service.ServiceName, service);
- st.Stop();
- log.Debug($"服务ID:{item.ID},名称:{item.ServiceName_Str},类型:{item.ServiceType_Str} 启动成功,耗时:{st.Elapsed}");
- }
- catch (Exception ex)
- {
- log.Warn($"服务ID:{item.ID},名称:{item.ServiceName_Str},类型:{item.ServiceType_Str} 启动失败:{ex.Message}");
- startTime = DateTime.Now;
- log.Error(ex);
- exMsg = ex.ToString();
- }
- finally
- {
- st?.Stop();
- }
- });
- serviceTasks.Add(task);
- task.Wait();
- }
- else
- {
- exMsg = $"没有找到 {item.ServiceName_Str}:{item.ServiceType_Str}";
- log.Warn(exMsg);
- }
- if (!string.IsNullOrEmpty(exMsg))
- {
- serviceState = "启动失败";
- }
- item.ServiceState_Str = serviceState;
- item.StartTime_Dt = startTime;
- item.ServiceMessage_Str = exMsg;
- }
- }
- Task.WaitAll(serviceTasks.ToArray());
- (serviceTable as BaseTable).Update(
- services, t => new { t.ID },
- t => new { t.ServiceState_Str, t.StartTime_Dt, t.ServiceMessage_Str });
- return true;
- }
- catch (Exception ex)
- {
- log.Error(ex);
- }
- return false;
- }
- /// <summary>
- /// 获取远程桌面的开启状态
- /// </summary>
- /// <returns></returns>
- private bool? GetTSState()
- {
- try
- {
- #if WINDOWS || NETFRAMEWORK
- Microsoft.Win32.RegistryKey registryRoot = Microsoft.Win32.Registry.LocalMachine;
- string[] path = new string[] { "SYSTEM", "CurrentControlSet", "Control", "Terminal Server", "" };
- foreach (string p in path)
- {
- if (registryRoot != null)
- registryRoot = registryRoot.OpenSubKey(p);
- }
- if (registryRoot != null)
- {
- return (int)registryRoot.GetValue("fDenyTSConnections") == 0;
- }
- #endif
- }
- catch (Exception)
- {
- }
- return null;
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public bool Stop()
- {
- if (isDisposed == false)
- {
- isDisposed = true;
- DisposeResource();
- }
- return true;
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public bool Paused()
- {
- //foreach (var item in MachineManage.GetInstance().GetAllMachine())
- //{
- // item.BaseProtocol?.Pause();
- //}
- //foreach (var item in Env.Instruments)
- //{
- // item.Value.Dispose();
- //}
- return true;
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public bool Resume()
- {
- //foreach (var item in MachineManage.GetInstance().GetAllMachine())
- //{
- // item.BaseProtocol?.Resume();
- //}
- return true;
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public bool Restart()
- {
- DisposeResource();
- System.Threading.Thread.Sleep(1 * 1000);
- Start();
- return true;
- }
- private bool DisposeResource()
- {
- isDisposed = true;
- var services = ServiceCollection.Values.ToList();
- for (int i = services.Count - 1; i >= 0; i--)
- {
- var item = services[i];
- try
- {
- log.Debug($"服务ID:{item.ServiceId},名称:{item.ServiceName} is Stopping");
- item.Stop();
- }
- catch (Exception ex)
- {
- log.Error(ex);
- }
- }
- ServiceCollection.Clear();
- return true;
- }
- /// <summary>
- ///
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
- public List<Type> GetPluginTypes<T>()
- {
- return GetPluginTypes<T>(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase
- .Replace("file:///", "")));
- }
- /// <summary>
- ///
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
- public List<Type> GetPluginTypes<T>(string basePath)
- {
- var typeList = new List<Type>();
- var assemblys = new List<Assembly>();
- if (Assembly.GetEntryAssembly() != null)
- {
- assemblys.Add(Assembly.GetEntryAssembly());
- }
- assemblys.Add(Assembly.GetEntryAssembly());
- var currentPath = string.IsNullOrEmpty(basePath) ? AppDomain.CurrentDomain.BaseDirectory : basePath;
- var files = new DirectoryInfo(currentPath).GetFiles(@"SCADA_DAQ.Plugin.*.dll");
- var pluginFiles = Directory.CreateDirectory($"{currentPath}\\plugin")
- .GetFiles(@"SCADA_DAQ.Plugin.*.dll");
- return ReflectionHelper.GetTypes<T>(files.Concat(pluginFiles).ToLookup(t => t.Name).Select(t => t.FirstOrDefault().FullName));
- }
- #region Web接口
- private List<Sys_Service> QueryServiceInfo()
- {
- return serviceTable.GetData().DtToList<Sys_Service>();
- }
- private bool ServiceIsRuning()
- {
- return true;
- }
- #endregion
- }
- }
|