App.xaml.cs 5.57 KB
using FreeSql;
using HHECS.DAQClient.Common;
using HHECS.DAQClient.Services;
using HHECS.DAQClient.ViewModel;
using HHECS.DAQClient.ViewModel.CommunicationVM;
using HHECS.DAQClient.ViewModel.EquipmentPropVM;
using HHECS.DAQClient.ViewModel.EquipmentVM;
using Microsoft.Extensions.DependencyInjection;
using NLog;
using System.Configuration;
using System.Diagnostics;
using System.Reflection;
using System.Windows;
using System.Windows.Threading;
using MessageBox = HandyControl.Controls.MessageBox;

namespace HHECS.DAQClient
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private static Mutex mutex;

        private readonly Logger _log = LogManager.GetCurrentClassLogger();

        public App()
        {
            Services = ConfigureServices();
            InitializeComponent();
        }

        /// <summary>
        /// Gets the current <see cref="App"/> instance in use
        /// </summary>
        public new static App Current => (App)Application.Current;

        /// <summary>
        /// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
        /// </summary>
        public IServiceProvider Services { get; }

        /// <summary>
        /// Configures the services for the application.
        /// </summary>
        private static ServiceProvider ConfigureServices()
        {
            var services = new ServiceCollection();
            var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
            IFreeSql fsql = new FreeSqlBuilder()
                .UseConnectionString(DataType.Sqlite, connectionString)
                //.UseMonitorCommand(cmd => Console.WriteLine($"Sql:{cmd.CommandText}"))//监听SQL语句
                .UseAutoSyncStructure(false) //自动同步实体结构到数据库,FreeSql不会扫描程序集,只有CRUD时才会生成表。
                .Build();

            services.AddSingleton(fsql);

            services.AddHttpClient<HttpService>().ConfigureHttpClient(client =>
            {
                _ = bool.TryParse(ConfigurationManager.AppSettings["IsProductionEnvironment"], out var isProductionEnvironment);
                var clientId = ConfigurationManager.AppSettings["ClientId"];
                var urlConfig = ConfigurationManager.AppSettings[isProductionEnvironment ? "ProductionAPI" : "TestAPI"]!;
                client.BaseAddress = new Uri(urlConfig);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                client.DefaultRequestHeaders.Add("User-Agent", "HHECS.DAQClient");
                client.DefaultRequestHeaders.Add("ClientId", clientId);
            });
            services.AddSingleton<CenterService>();

            // DataAnalysis
            //services.AddScoped<IAnalysis, FanucAnalysis>();

            // Viewmodels
            services.AddTransient<MainVM>();
            services.AddTransient<EquipmentVM>();
            services.AddTransient<EquipmentAddOrEditVM>();

            services.AddTransient<EquipmentPropMonitorVM>();

            services.AddTransient<CommunicationVM>();
            services.AddTransient<CommunicationAddOrEditVM>();

            services.AddTransient<EquipmentDataQueueVM>();
            services.AddTransient<PrivacyInfoVM>();

            return services.BuildServiceProvider();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            //UI线程未捕获异常处理事件(UI主线程)
            DispatcherUnhandledException += App_DispatcherUnhandledException;
            //非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

            var process = Process.GetProcessesByName($"{Assembly.GetExecutingAssembly().GetName().Name}");
            _ = bool.TryParse(ConfigurationManager.AppSettings["IsProductionEnvironment"], out var isProductionEnvironment);
            mutex = new Mutex(false, $"{process}_{ConfigurationManager.AppSettings["ClientId"]}_{isProductionEnvironment}");

            if (!mutex.WaitOne(TimeSpan.Zero, true))
            {
                MessageBox.Warning("应用程序已在运行!");
                Shutdown();
                return;
            }

            Application.Current.Exit += (s, args) =>
            {
                mutex.ReleaseMutex();
                mutex.Close();
            };
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            Exception ex = e.Exception;
            _log.Debug($"UI线程异常{ex}");
            e.SetObserved();
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is Exception ex)
            {
                _log.Debug($"非UI线程异常{ex}", LogType.Debug);
            }
        }

        private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            Exception ex = e.Exception;
            string msg = string.Format("{0}\n\n{1}", ex.Message, ex.StackTrace);//异常信息 和 调用堆栈信息
            MessageBox.Error("UI线程异常", msg);
            _log.Debug($"UI线程异常{ex}");
            e.Handled = true;//表示异常已处理,可以继续运行
        }
    }
}