using System; using System.Linq; using System.Text; using System.Threading; using System.Windows; using System.Windows.Threading; namespace JJServiceManager { public static class Program { private const string MutexName = "JJServiceManager_SingleInstance_Mutex"; private const string ShowEventName = "JJServiceManager_SingleInstance_Show"; [STAThread] public static int Main(string[] args) { // CP949(한국어 ANSI) 로그 파일 읽기용 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // 한 번만 실행: 이미 실행 중이면 기존 창을 띄우고 종료 using var mutex = new Mutex(true, MutexName, out bool createdNew); if (!createdNew) { // 기존 창이 앞으로 나올 수 있도록 허용 AllowSetForegroundWindow(-1); // 첫 번째 실행이 아직 준비 중일 수 있으므로 잠시 재시도 for (int i = 0; i < 20; i++) { try { using var ev = EventWaitHandle.OpenExisting(ShowEventName); ev.Set(); break; } catch { Thread.Sleep(250); } } return 0; } using var showEvent = new EventWaitHandle(false, EventResetMode.AutoReset, ShowEventName); var app = new Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; app.Resources.MergedDictionaries.Add((ResourceDictionary)XamlLoader.Load("Styles.xaml")); app.DispatcherUnhandledException += OnUnhandled; AppDomain.CurrentDomain.UnhandledException += (s, e) => OperationLogFile.Append(DateTime.Now, "처리되지 않은 오류: " + e.ExceptionObject); var settings = SettingsStore.Load(); bool startInTray = args.Any(a => string.Equals(a, "--tray", StringComparison.OrdinalIgnoreCase)); var main = new MainWindow(settings); app.SessionEnding += (s, e) => main.OnSessionEnding(); if (!startInTray) main.Show(); // 두 번째 실행 신호를 받으면 창 표시 var waiter = new Thread(() => { while (true) { try { showEvent.WaitOne(); if (app.Dispatcher.HasShutdownStarted) return; app.Dispatcher.BeginInvoke(new Action(main.ShowFromTray)); } catch { return; } } }) { IsBackground = true, Name = "SingleInstanceWaiter" }; waiter.Start(); return app.Run(); } [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern bool AllowSetForegroundWindow(int dwProcessId); private static void OnUnhandled(object sender, DispatcherUnhandledExceptionEventArgs e) { OperationLogFile.Append(DateTime.Now, "오류: " + e.Exception); MessageBox.Show("예상하지 못한 오류가 발생했습니다.\n\n" + e.Exception.Message, "JJServiceManager", MessageBoxButton.OK, MessageBoxImage.Warning); e.Handled = true; } } }