using FISLib; using FISLib.AfterSales; using FISLib.Connect; using FISLib.Consultation; using FISLib.Hardware; using FISLib.LiveVideo; using FISLib.Log; using FISLib.Notification; using FISLib.Remedical; using FISLib.Teaching; using FISLib.Test; using FISLib.Translator; using FISLib.Upgrade; using FISLib.Vid; using FISLib.vStation; using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using Vinno.IUS.Common.Log; using Vinno.IUS.Common.Network; using Vinno.vCloud.Common.FIS.Log; using Vinno.vCloud.FIS.CrossPlatform.Common; using Vinno.vCloud.FIS.CrossPlatform.Common.Helper; namespace FISIMPL { public class FISIMPL { private static readonly Dictionary _serviceDictionary = new Dictionary(); private static PipeServer _pipeServer; private static LogEngine _logEngine; private static Task _checkUltrasoundExeTask; private static CancellationTokenSource _cancellationTokenSource; /// /// Gets or sets if it is running in JsonRpc Mode /// internal static bool IsRunningJsonRpcMode { get; private set; } internal static UltrasoundMachineInfo UltrasoundMachineInfo { get; private set; } internal static FISPlatform Platform { get; private set; } public static bool IsConnectWithOldServer { get; private set; } public static string FISLogBasePath { get; private set; } /// /// Raised when close FIS Exe /// public static event EventHandler CloseFISExeEvent; public static void InitFISLogPath(string baseDirectory = null) { string logPath; if (string.IsNullOrEmpty(baseDirectory)) { FISLogBasePath = AppDomain.CurrentDomain.BaseDirectory; } else { FISLogBasePath = baseDirectory; } logPath = Path.Combine(FISLogBasePath, "FISLogs"); DirectoryHelper.CreateDirectory(logPath); CommonInitializer.Initialize(logPath); if (_logEngine == null) { _logEngine = new FISLogEngine(); Logger.RegisterEngine(_logEngine); CrossPlatformHelper.Instance.LogWriter = new LogWriter(); } } public static void InitLogEngine(LogEngine logEngine) { if (_logEngine == null) { _logEngine = logEngine; Logger.RegisterEngine(_logEngine); CrossPlatformHelper.Instance.LogWriter = new LogWriter(); } } /// /// Star the FISIMPL in Windows/Android. /// public static void Start(string machineId, FISPlatform platform = FISPlatform.Windows, bool isRunningJsonRpcMode = true) { try { Logger.WriteLineInfo("Ready To Start FISIMPL"); AppDomain.CurrentDomain.UnhandledException += OnDomainOnUnhandledException; if (machineId.Length > 1) { CommonParameter.Instance.MachineId = machineId; } else { CommonParameter.Instance.MachineId = "Unknown"; } Platform = platform; IsRunningJsonRpcMode = isRunningJsonRpcMode; var currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); Logger.WriteLineInfo($"FISIMPL Current Version is{currentVersion}"); RegisterServices(); FIS.FISLogInfoNotificated += OnFISLogInfoNotificated; if (IsRunningJsonRpcMode) { switch (Platform) { case FISPlatform.Windows: StartInWindows(); break; case FISPlatform.Android: StartInAndroid(); break; } } } catch (Exception ex) { Logger.WriteLineError($"FISIMPL Start Error,{ex}"); DisposePipeServer(); throw; } } public static void ChangeMachineId(string machineId) { if (!string.IsNullOrEmpty(machineId)) { CommonParameter.Instance.MachineId = machineId; } } private static void OnFISLogInfoNotificated(object sender, FISLogEventArgs e) { Logger.WriteLineWarn($"OnFISLogInfoNotificated Invoke {e.Msg}"); } private static void RegisterServices() { switch (Platform) { case FISPlatform.Windows: var connectionService = new ConnectionService(); _serviceDictionary.Add(typeof(IConnectionService), connectionService); var remedicalService = new RemedicalService(); _serviceDictionary.Add(typeof(IRemedicalService), remedicalService); var vStationService = new VStationService(); _serviceDictionary.Add(typeof(IvStationService), vStationService); var vidServiceForWindows = new VidServiceForWindows(); _serviceDictionary.Add(typeof(IVidService), vidServiceForWindows); var translatorService = new TranslatorService(); _serviceDictionary.Add(typeof(ITranslatorService), translatorService); var upgraderService = new UpgraderService(); _serviceDictionary.Add(typeof(IUpgraderService), upgraderService); var teachingService = new TeachingService(); _serviceDictionary.Add(typeof(ITeachingService), teachingService); var liveVideoServiceForWindows = new LiveVideoServiceForWindows(); _serviceDictionary.Add(typeof(ILiveVideoService), liveVideoServiceForWindows); //var logService = new LogService(); //_serviceDictionary.Add(typeof(ILogService), logService); var testService = new TestService(); _serviceDictionary.Add(typeof(ITestService), testService); var consultationServiceForWindows = new ConsultationServiceForWindows(); _serviceDictionary.Add(typeof(IConsultationService), consultationServiceForWindows); var afterSalesService = new AfterSalesService(); _serviceDictionary.Add(typeof(IAfterSalesService), afterSalesService); var hardwareServiceForWindows = new HardwareServiceForWindows(); _serviceDictionary.Add(typeof(IHardwareService), hardwareServiceForWindows); break; case FISPlatform.Android: connectionService = new ConnectionService(); _serviceDictionary.Add(typeof(IConnectionService), connectionService); remedicalService = new RemedicalService(); _serviceDictionary.Add(typeof(IRemedicalService), remedicalService); vStationService = new VStationService(); _serviceDictionary.Add(typeof(IvStationService), vStationService); var vidServiceForAndroid = new VidServiceForAndroid(); _serviceDictionary.Add(typeof(IVidService), vidServiceForAndroid); translatorService = new TranslatorService(); _serviceDictionary.Add(typeof(ITranslatorService), translatorService); upgraderService = new UpgraderService(); _serviceDictionary.Add(typeof(IUpgraderService), upgraderService); teachingService = new TeachingService(); _serviceDictionary.Add(typeof(ITeachingService), teachingService); var liveVideoServiceForAndroid = new LiveVideoServiceForAndroid(); _serviceDictionary.Add(typeof(ILiveVideoService), liveVideoServiceForAndroid); //logService = new LogService(); //_serviceDictionary.Add(typeof(ILogService), logService); testService = new TestService(); _serviceDictionary.Add(typeof(ITestService), testService); var consultationServiceForAndroid = new ConsultationServiceForAndroid(); _serviceDictionary.Add(typeof(IConsultationService), consultationServiceForAndroid); afterSalesService = new AfterSalesService(); _serviceDictionary.Add(typeof(IAfterSalesService), afterSalesService); var hardwareServiceForAndroid = new HardwareServiceForAndroid(); _serviceDictionary.Add(typeof(IHardwareService), hardwareServiceForAndroid); break; } } public static T GetService() where T : IService { var type = typeof(T); if (_serviceDictionary.ContainsKey(type)) { return (T)_serviceDictionary[type]; } throw new NullReferenceException($"Can not find instance for type{type}"); } internal static void DisposeAllService() { foreach (var service in _serviceDictionary) { try { if (service.Value is IDisposable dispose) { dispose.Dispose(); } } catch (Exception e) { Logger.WriteLineError($"Dispose Service {service.Key} failed, ex: {e}"); } } _serviceDictionary.Clear(); Logger.WriteLineInfo($"FISIMPL DisposeAllService success"); } /// /// Stop the FISIMPL /// public static void Stop() { Logger.WriteLineInfo("FISIMPL Stop Invoke"); _cancellationTokenSource?.Cancel(); try { _checkUltrasoundExeTask?.Wait(1000);//因Task在Wait过程中Cancel有几率会出错 } catch { } DisposeAllService(); if (IsRunningJsonRpcMode) { FISJsonRpcServer.Stop(); NotificationSender.Dispose(); } if (_logEngine != null) { _logEngine.Dispose(); _logEngine = null; } AppDomain.CurrentDomain.UnhandledException -= OnDomainOnUnhandledException; FIS.FISLogInfoNotificated -= OnFISLogInfoNotificated; } public static void SetIsConnectWithOldServer(bool isConnectWithOldServer) { IsConnectWithOldServer = isConnectWithOldServer; NotificationSender.SendNotification(new FISNotificationArgs { NotificationType = FISNotificationType.FISConnectIsConnectWithOldServer, Params = isConnectWithOldServer, }); } public static void SetUltrasoundMachineInfo(UltrasoundMachineInfo ultrasoundMachineInfo) { UltrasoundMachineInfo = ultrasoundMachineInfo; } private static void StartInWindows() { string processName = null; FISJsonRpcServer.Start(); NotificationSender.Initialize(); CreatePipeServer(); Logger.WriteLineInfo($"FISMPL Start to Pair with Ultrasonic Software"); if (_pipeServer.Start(60000)) { Logger.WriteLineInfo($"FISMPL Pair Success"); var processNameBytes = _pipeServer.ReceiveBytes(); processName = Encoding.Unicode.GetString(processNameBytes); DisposePipeServer(); } else { Logger.WriteLineError($"FISMPL Pair Fail"); DisposePipeServer(); Logger.WriteLineError($"CloseFISExeEvent Start to Invoke"); CloseFISExeEvent?.Invoke(null, EventArgs.Empty); return; } if (string.IsNullOrWhiteSpace(processName)) { Logger.WriteLineError($"FISMPL The ProcessName is empty,CloseFISExeEvent Start to Invoke"); CloseFISExeEvent?.Invoke(null, EventArgs.Empty); return; } _cancellationTokenSource = new CancellationTokenSource(); _checkUltrasoundExeTask = new Task(() => { while (!_cancellationTokenSource.IsCancellationRequested) { try { if (!CheckIsUltrasoundExeExist(processName)) { Logger.WriteLineError($"FISMPL checkUltrasoundExe Task:The UltrasoundExe is not Exist,it will Close"); _cancellationTokenSource.Cancel(); ProcessHelper.FinishProcessByName("Vinno.FIS.TRTCClient"); Task.Run(() =>//之所以起Task,是因为Stop的时候会wait checkUltrasoundExeTask. { Logger.WriteLineError($"CloseFISExeEvent Start to Invoke"); CloseFISExeEvent?.Invoke(null, EventArgs.Empty); }); } else { Thread.Sleep(1000); } } catch (Exception ex) { Logger.WriteLineError($"CheckUltrasoundExe Task Error:{ex}"); } } }, _cancellationTokenSource.Token); _checkUltrasoundExeTask.Start(); Logger.WriteLineInfo($"FISMPL Start checkUltrasoundExe Task"); } public static void WriterLineInfo(string msg) { Logger.WriteLineInfo(msg); } public static void WriteLineWarn(string msg) { Logger.WriteLineWarn(msg); } public static void WriteLineError(string msg) { Logger.WriteLineError(msg); } private static void CreatePipeServer() { if (_pipeServer == null) { _pipeServer = new PipeServer(FISConsts.PipeForFISExeBootUpCheck); _pipeServer.LogMsgThrow += OnLogMsgThrow; } Logger.WriteLineInfo($"CreatePipeServer {FISConsts.PipeForFISExeBootUpCheck} Success"); } private static void DisposePipeServer() { if (_pipeServer != null) { _pipeServer.Dispose(); _pipeServer.LogMsgThrow -= OnLogMsgThrow; _pipeServer = null; } Logger.WriteLineInfo($"DisposePipeServer {FISConsts.PipeForFISExeBootUpCheck} Success"); } private static void OnLogMsgThrow(object sender, FISLogEventArgs e) { if (e == null) { return; } switch (e.LogType) { case FISDeviceLogCategory.Error: Logger.WriteLineError(e.Msg); break; case FISDeviceLogCategory.Warn: Logger.WriteLineWarn(e.Msg); break; case FISDeviceLogCategory.Verb: Logger.WriteLineVerbose(e.Msg); break; case FISDeviceLogCategory.Info: default: Logger.WriteLineInfo(e.Msg); break; } } private static void StartInAndroid() { FISJsonRpcServer.Start(); NotificationSender.Initialize(); } private static void OnDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) { Logger.WriteLineError($"OnDomainOnUnhandledException:{e.ExceptionObject}"); } private static bool CheckIsUltrasoundExeExist(string processName) { return ProcessHelper.IsProcessExistByName(processName); } public static void WriteInfoLog(string logMsg) { Logger.WriteLineInfo(logMsg); } public static void WriteErrorLog(string logMsg) { Logger.WriteLineError(logMsg); } public static void WriteWarnLog(string logMsg) { Logger.WriteLineWarn(logMsg); } } }