App.xaml.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Windows;
  5. using System.Windows.Threading;
  6. using vStation.Module.Login;
  7. using vStation.Module.Status;
  8. using vStation.Module.SystemSetting;
  9. using vStation.Module.Workstation;
  10. using System.Runtime.InteropServices;
  11. using vStation.Infrastructure;
  12. using vStation.Utilities.Report;
  13. using Vinno.IUS.Common.Utilities;
  14. using System.Threading.Tasks;
  15. using vStation.PipeLine;
  16. using vStation.URMStationRelevant;
  17. using Newtonsoft.Json;
  18. using System.Collections.Generic;
  19. using URMServiceConfig;
  20. using JsonRpcLite.Rpc;
  21. using JsonRpcLite.Network;
  22. using WingInterfaceLibrary.Interface;
  23. using JsonRpcLite.Services;
  24. using NPOI.SS.Formula.Functions;
  25. using System.Threading;
  26. namespace vStation
  27. {
  28. /// <summary>
  29. /// App.xaml 的交互逻辑
  30. /// </summary>
  31. public partial class App : Application
  32. {
  33. /// <summary>
  34. /// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
  35. /// </summary>
  36. /// <param name="hWnd">将被激活并被调入前台的窗口句柄。</param>
  37. /// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns>
  38. [DllImport("User32.dll")]
  39. private static extern bool SetForegroundWindow(IntPtr hWnd);
  40. [DllImport("User32.dll")]
  41. private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
  42. private DefaultLogEngine _defaultLogEngine;
  43. private UserLogEngine _userLogEngine;
  44. protected override void OnStartup(StartupEventArgs e)
  45. {
  46. CheckedOpenRepeatedly(e.Args);
  47. //NetworkException.RegisterConverter(new NetworkExceptionConverter());
  48. XmlHelper.RegisterXmlEngine(new XmlEngine());
  49. InitializeLanguage();
  50. IoHelper.RegisterEngine(new IoEngine(AppDomain.CurrentDomain.BaseDirectory));
  51. _defaultLogEngine = new DefaultLogEngine();
  52. _userLogEngine = new UserLogEngine();
  53. UserLogger.RegisterEngine(_userLogEngine);
  54. Logger.RegisterEngine(_defaultLogEngine);
  55. AppDomain.CurrentDomain.UnhandledException += OnDomainOnUnhandledException;
  56. Current.DispatcherUnhandledException += OnDispatcherUnhandledException;
  57. Current.Exit += OnExit;
  58. AppManager.Instance.RegisterFunction(typeof(IDbService), new DbService());
  59. AppManager.Instance.RegisterFunction(typeof(Module.Login.ILoginService), new LoginService());
  60. AppManager.Instance.RegisterFunction(typeof(ISystemSettingManager), new SystemSettingManager());
  61. AppManager.Instance.RegisterFunction(typeof(ISystemSettingExamPointFee), new SystemSettingExamPointFee());
  62. Config.IsURMStation = true;
  63. if (Config.IsURMStation)
  64. {
  65. IntiURMStation();
  66. }
  67. base.OnStartup(e);
  68. }
  69. private void IntiURMStation()
  70. {
  71. // "E:\\FISShellRev\\fis\\fis\\fis\\bin\\Debug\\net6.0";
  72. URMConfig.URMWorkingDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "URMWorkStation") ;
  73. if (!Directory.Exists(URMConfig.StorageDirectory))
  74. {
  75. Directory.CreateDirectory(URMConfig.StorageDirectory);
  76. }
  77. RootObject root=null;
  78. var isSingle= URMConfig.GetIsSingleMode();
  79. if (File.Exists(URMConfig.ConfigPath))
  80. {
  81. try
  82. {
  83. var data = File.ReadAllText(URMConfig.ConfigPath);
  84. root = JsonConvert.DeserializeObject<RootObject>(data);
  85. }
  86. catch (Exception ex)
  87. {
  88. Logger.WriteLineError($"Error happened while init urm station{ex}");
  89. }
  90. }
  91. else {
  92. if (root == null)
  93. {
  94. root = new RootObject();
  95. root.flyinsonoServers = new List<string>();
  96. root.flyinsonoServers.Add("https://bj.flyinsono.com");
  97. root.common = new Common();
  98. root.server = new URMServiceConfig.Server();
  99. root.common.dateTimeFormat = "yyyy-MM-dd HH:mm";
  100. root.server.current = "http://127.0.0.1:8303";
  101. root.server.optionSource = new List<string>();
  102. root.server.optionSource.Add("http://127.0.0.1:8303");
  103. }
  104. }
  105. URMConfig.RPCAddress = root.server.current;
  106. if (isSingle)
  107. {
  108. root.server.current = "http://127.0.0.1:8303";
  109. var txt = JsonConvert.SerializeObject(root);
  110. URMConfig.ServerStatusChanged += OnServerStatusChanged;
  111. URMConfig.ServerStatus = ServerStatus.NeedStartServer;
  112. File.WriteAllText(URMConfig.ConfigPath, txt);
  113. }
  114. }
  115. private void OnServerStatusChanged(object sender, ServerStatus e)
  116. {
  117. if (e == ServerStatus.NeedStartServer)
  118. {
  119. GetServerState(URMConfig.RPCAddress);
  120. return;
  121. }
  122. if (e == ServerStatus.Starting)
  123. {
  124. ControlServer(true);
  125. return;
  126. }
  127. Logger.WriteLineVerbose($"Server starting result is:--- {e}");
  128. }
  129. private void ControlServer(bool isOpen, bool isRestart = false)
  130. {
  131. Logger.WriteLineInfo($"Server start batch file not exist!");
  132. var targetPath = isOpen ? URMConfig.StartServerBatchFile : URMConfig.CloseServerBatchFile;
  133. if (!File.Exists(targetPath))
  134. {
  135. Logger.WriteLineError($"Server start batch file not exist!");
  136. return;
  137. }
  138. ProcessStartInfo processInfo2 = new ProcessStartInfo(targetPath)
  139. {
  140. CreateNoWindow = true,
  141. UseShellExecute = false,
  142. RedirectStandardError = true,
  143. RedirectStandardOutput = true,
  144. Verb = "runas",
  145. // 不使用操作系统外壳程序启动进程
  146. };
  147. Process.Start(processInfo2);
  148. Task.Run
  149. (() =>
  150. {
  151. if (isOpen)
  152. {
  153. int count = 0;
  154. while (URMConfig.ServerStatus==ServerStatus.Starting)
  155. {
  156. count++;
  157. Thread.Sleep(2000);
  158. GetServerState(URMConfig.RPCAddress);
  159. if (count == 30)
  160. {
  161. URMConfig.ServerStatus = ServerStatus.StartingTimeout;
  162. break;
  163. }
  164. }
  165. }
  166. });
  167. }
  168. private void GetServerState(string address)
  169. {
  170. Task.Run(async () => {
  171. var isConnected = await ValidateServerAddress(address);
  172. if (isConnected)
  173. {
  174. URMConfig.ServerStatus = ServerStatus.Started;
  175. }
  176. else
  177. {
  178. URMConfig.ServerStatus=ServerStatus.Starting;
  179. }
  180. });
  181. }
  182. private async Task<bool> ValidateServerAddress(string address)
  183. {
  184. try
  185. {
  186. var client = new JsonRpcClient();
  187. var clientEngine = new JsonRpcHttpClientEngine(address);
  188. clientEngine.Timeout = 1000;
  189. client.UseEngine(clientEngine);
  190. var loginService = client?.CreateProxy<WingInterfaceLibrary.Interface.ILoginService>();
  191. if (loginService == null)
  192. {
  193. return false;
  194. }
  195. var result = await loginService.CommonLoginAsync(new WingInterfaceLibrary.Request.User.CommonLoginRequest()
  196. {
  197. });
  198. if (result == null)
  199. {
  200. return false;
  201. }
  202. if (result.LoginState == WingInterfaceLibrary.Enum.LoginStateEnum.SignOrLoginFail ||
  203. result.LoginState == WingInterfaceLibrary.Enum.LoginStateEnum.PasswordIncorrect
  204. )
  205. {
  206. return true;
  207. }
  208. }
  209. catch (RpcException ex)
  210. {
  211. return true;
  212. }
  213. catch (Exception ex)
  214. {
  215. return false;
  216. }
  217. finally
  218. {
  219. }
  220. return true;
  221. }
  222. /// <summary>
  223. /// 判断是否重复打开
  224. /// </summary>
  225. /// <param name="checkedIndex">判断次数,每次间隔1秒,判断结束,窗口依旧存在,则取消此次运行</param>
  226. private void CheckedOpenRepeatedly(string[] Args = null)
  227. {
  228. var thisProcess = Process.GetCurrentProcess();
  229. foreach (var item in Process.GetProcessesByName(thisProcess.ProcessName))
  230. {
  231. if (thisProcess.Id != item.Id)
  232. {
  233. if ((Args != null && Args.Length > 0 && Args[0] == "RestoreData")||string.IsNullOrEmpty(item.MainWindowTitle))
  234. {
  235. item.Close();
  236. }
  237. else
  238. {
  239. ShowWindow(item.MainWindowHandle, 9);
  240. SetForegroundWindow(item.MainWindowHandle);
  241. Current.Shutdown();
  242. }
  243. }
  244. }
  245. }
  246. private void OnExit(object sender, ExitEventArgs e)
  247. {
  248. _defaultLogEngine.Dispose();
  249. _userLogEngine.Dispose();
  250. var thisProcess = Process.GetCurrentProcess();
  251. thisProcess.Kill();
  252. }
  253. private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
  254. {
  255. Logger.WriteLineError($"Unhandled exception:{e.Exception}");
  256. e.Handled = true;
  257. ShowExceptionWindow(e.Exception.Message);
  258. }
  259. private void OnDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
  260. {
  261. Logger.WriteLineError($"Unhandled exception:{e.ExceptionObject}");
  262. var exception = e.ExceptionObject as Exception;
  263. if (exception == null)
  264. {
  265. ShowExceptionWindow(e.ExceptionObject.ToString());
  266. }
  267. else
  268. {
  269. ShowExceptionWindow(exception.ToString());
  270. }
  271. }
  272. private void ShowExceptionWindow(string exceptionMessage)
  273. {
  274. var statusService = AppManager.Instance.GetFunction<IStatusService>();
  275. var popupInfo = new PopupInfo(TranslateHelper.Translate("Error"), exceptionMessage, PopupIconType.Error);
  276. statusService?.ShowPopup(popupInfo);
  277. }
  278. private void InitializeLanguage()
  279. {
  280. var assemblyName = GetType().Assembly.GetName().Name;
  281. foreach (var supportedLanguage in TranslateHelper.SupportedLanguages)
  282. {
  283. var resourceName = $"{assemblyName}.Languages.{supportedLanguage}.json";
  284. using (var languageStream = GetType().Assembly.GetManifestResourceStream(resourceName))
  285. {
  286. if (languageStream != null)
  287. {
  288. var reader = new StreamReader(languageStream);
  289. var content = reader.ReadToEnd();
  290. TranslateHelper.AddLanguageResource(supportedLanguage, content);
  291. }
  292. }
  293. }
  294. }
  295. }
  296. public class RootObject
  297. {
  298. public Common common { get; set; }
  299. public URMServiceConfig.Server server { get; set; }
  300. public List<string> flyinsonoServers { get; set; }
  301. }
  302. public class Common
  303. {
  304. public string dateTimeFormat { get; set; }
  305. }
  306. }
  307. namespace URMServiceConfig
  308. {
  309. public class Server
  310. {
  311. public string current { get; set; }
  312. public List<string> optionSource { get; set; }
  313. }
  314. }