using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Threading; using AxCopilot.Core; using AxCopilot.Handlers; using AxCopilot.Models; using AxCopilot.Security; using AxCopilot.Services; using AxCopilot.ViewModels; using AxCopilot.Views; using Microsoft.Win32; namespace AxCopilot; public class App : System.Windows.Application { private static class NativeMethods { public struct INPUT { public uint type; public InputUnion u; } [StructLayout(LayoutKind.Explicit)] public struct InputUnion { [FieldOffset(0)] public KEYBDINPUT ki; } public struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public nint dwExtraInfo; } [DllImport("user32.dll")] public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); } [Serializable] [CompilerGenerated] private sealed class _003C_003Ec { public static readonly _003C_003Ec _003C_003E9 = new _003C_003Ec(); public static DispatcherUnhandledExceptionEventHandler _003C_003E9__24_0; public static Action _003C_003E9__31_10; public static Action _003C_003E9__31_17; public static Action _003C_003E9__31_18; public static Action _003C_003E9__31_13; public static Action _003C_003E9__31_19; internal void _003COnStartup_003Eb__24_0(object _, DispatcherUnhandledExceptionEventArgs ex) { LogService.Error($"미처리 예외: {ex.Exception}"); CustomMessageBox.Show("오류가 발생했습니다:\n" + ex.Exception.Message + "\n\n로그 폴더를 확인하세요.", "AX Copilot 오류", MessageBoxButton.OK, MessageBoxImage.Hand); ex.Handled = true; } internal void _003CSetupTrayIcon_003Eb__31_10() { string arguments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "logs"); Process.Start(new ProcessStartInfo("explorer.exe", arguments) { UseShellExecute = true }); } internal void _003CSetupTrayIcon_003Eb__31_17() { new StatisticsWindow().Show(); } internal void _003CSetupTrayIcon_003Eb__31_18() { new GuideViewerWindow().Show(); } internal void _003CSetupTrayIcon_003Eb__31_13(bool isChecked) { SetAutoStart(isChecked); } internal void _003CSetupTrayIcon_003Eb__31_19() { new AboutWindow().Show(); } } private Mutex? _singleInstanceMutex; private InputListener? _inputListener; private LauncherWindow? _launcher; private NotifyIcon? _trayIcon; private TrayMenuWindow? _trayMenu; private SettingsService? _settings; private SettingsWindow? _settingsWindow; private PluginHost? _pluginHost; private ClipboardHistoryService? _clipboardHistory; private DockBarWindow? _dockBar; private FileDialogWatcher? _fileDialogWatcher; private volatile IndexService? _indexService; private SessionTrackingService? _sessionTracking; private WorktimeReminderService? _worktimeReminder; private ScreenCaptureHandler? _captureHandler; private AgentMemoryService? _memoryService; private ChatWindow? _chatWindow; private const string AutoRunKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; private const string AutoRunName = "AxCopilot"; private bool _contentLoaded; public IndexService? IndexService => _indexService; public SettingsService? SettingsService => _settings; public ClipboardHistoryService? ClipboardHistoryService => _clipboardHistory; public AgentMemoryService? MemoryService => _memoryService; protected override void OnStartup(StartupEventArgs e) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown base.OnStartup(e); AntiTamper.Check(); object obj = _003C_003Ec._003C_003E9__24_0; if (obj == null) { DispatcherUnhandledExceptionEventHandler val = delegate(object _, DispatcherUnhandledExceptionEventArgs ex) { LogService.Error($"미처리 예외: {ex.Exception}"); CustomMessageBox.Show("오류가 발생했습니다:\n" + ex.Exception.Message + "\n\n로그 폴더를 확인하세요.", "AX Copilot 오류", MessageBoxButton.OK, MessageBoxImage.Hand); ex.Handled = true; }; _003C_003Ec._003C_003E9__24_0 = val; obj = (object)val; } base.DispatcherUnhandledException += (DispatcherUnhandledExceptionEventHandler)obj; _singleInstanceMutex = new Mutex(initiallyOwned: true, "Global\\AXCopilot_SingleInstance", out var createdNew); if (!createdNew) { _singleInstanceMutex.Dispose(); _singleInstanceMutex = null; CustomMessageBox.Show("AX Copilot가 이미 실행 중입니다.\n트레이 아이콘을 확인하세요.", "AX Copilot", MessageBoxButton.OK, MessageBoxImage.Asterisk); Shutdown(); return; } LogService.Info("=== AX Copilot 시작 ==="); _settings = new SettingsService(); SettingsService settings = _settings; settings.Load(); if (settings.MigrationSummary != null) { ((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate { CustomMessageBox.Show(settings.MigrationSummary, "AX Copilot — 설정 업데이트", MessageBoxButton.OK, MessageBoxImage.Asterisk); }, (DispatcherPriority)6, Array.Empty()); } L10n.SetLanguage(settings.Settings.Launcher.Language); if (!IsAutoStartEnabled()) { SetAutoStart(enable: true); } _memoryService = new AgentMemoryService(); _memoryService.Load(settings.Settings.Llm.WorkFolder); _indexService = new IndexService(settings); IndexService indexService = _indexService; FuzzyEngine fuzzy = new FuzzyEngine(indexService); CommandResolver commandResolver = new CommandResolver(fuzzy, settings); ContextManager context = new ContextManager(settings); _sessionTracking = new SessionTrackingService(); _worktimeReminder = new WorktimeReminderService(settings, ((DispatcherObject)this).Dispatcher); _clipboardHistory = new ClipboardHistoryService(settings); commandResolver.RegisterHandler(new CalculatorHandler()); commandResolver.RegisterHandler(new SystemCommandHandler(settings)); commandResolver.RegisterHandler(new SnippetHandler(settings)); commandResolver.RegisterHandler(new ClipboardHistoryHandler(_clipboardHistory)); commandResolver.RegisterHandler(new WorkspaceHandler(context, settings)); commandResolver.RegisterHandler(new UrlAliasHandler(settings)); commandResolver.RegisterHandler(new FolderAliasHandler(settings)); commandResolver.RegisterHandler(new BatchHandler(settings)); commandResolver.RegisterHandler(new ClipboardHandler(settings)); commandResolver.RegisterHandler(new BookmarkHandler()); commandResolver.RegisterHandler(new WebSearchHandler(settings)); commandResolver.RegisterHandler(new ProcessHandler()); commandResolver.RegisterHandler(new MediaHandler()); commandResolver.RegisterHandler(new SystemInfoHandler()); commandResolver.RegisterHandler(new StarInfoHandler()); commandResolver.RegisterHandler(new EmojiHandler()); commandResolver.RegisterHandler(new ColorHandler()); commandResolver.RegisterHandler(new RecentFilesHandler()); commandResolver.RegisterHandler(new NoteHandler()); commandResolver.RegisterHandler(new UninstallHandler()); commandResolver.RegisterHandler(new PortHandler()); commandResolver.RegisterHandler(new EnvHandler()); commandResolver.RegisterHandler(new JsonHandler()); commandResolver.RegisterHandler(new EncodeHandler()); commandResolver.RegisterHandler(new SnapHandler()); _captureHandler = new ScreenCaptureHandler(settings); commandResolver.RegisterHandler(_captureHandler); commandResolver.RegisterHandler(new ColorPickHandler()); commandResolver.RegisterHandler(new DateCalcHandler()); commandResolver.RegisterHandler(new ServiceHandler(_clipboardHistory)); commandResolver.RegisterHandler(new ClipboardPipeHandler()); commandResolver.RegisterHandler(new JournalHandler()); commandResolver.RegisterHandler(new RoutineHandler()); commandResolver.RegisterHandler(new BatchTextHandler()); commandResolver.RegisterHandler(new DiffHandler(_clipboardHistory)); commandResolver.RegisterHandler(new WindowSwitchHandler()); commandResolver.RegisterHandler(new RunHandler()); commandResolver.RegisterHandler(new TextStatsHandler()); commandResolver.RegisterHandler(new FavoriteHandler()); commandResolver.RegisterHandler(new RenameHandler()); commandResolver.RegisterHandler(new MonitorHandler()); commandResolver.RegisterHandler(new ScaffoldHandler()); commandResolver.RegisterHandler(new EverythingHandler()); commandResolver.RegisterHandler(new HelpHandler(settings)); commandResolver.RegisterHandler(new ChatHandler(settings)); PluginHost pluginHost = new PluginHost(settings, commandResolver); pluginHost.LoadAll(); _pluginHost = pluginHost; LauncherViewModel vm = new LauncherViewModel(commandResolver, settings); _launcher = new LauncherWindow(vm) { OpenSettingsAction = OpenSettings }; ((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate { _clipboardHistory?.Initialize(); }, (DispatcherPriority)2, Array.Empty()); ((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate { PrewarmChatWindow(); }, (DispatcherPriority)1, Array.Empty()); indexService.BuildAsync().ContinueWith(delegate { indexService.StartWatchers(); }); _inputListener = new InputListener(); _inputListener.HotkeyTriggered += OnHotkeyTriggered; _inputListener.CaptureHotkeyTriggered += OnCaptureHotkeyTriggered; _inputListener.HookFailed += OnHookFailed; _inputListener.UpdateHotkey(settings.Settings.Hotkey); _inputListener.UpdateCaptureHotkey(settings.Settings.ScreenCapture.GlobalHotkey, settings.Settings.ScreenCapture.GlobalHotkeyEnabled); SnippetExpander snippetExpander = new SnippetExpander(settings); _inputListener.KeyFilter = snippetExpander.HandleKey; _inputListener.Start(); SetupTrayIcon(pluginHost, settings); _fileDialogWatcher = new FileDialogWatcher(); _fileDialogWatcher.FileDialogOpened += delegate { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { if (_launcher != null && !_launcher.IsVisible) { SettingsService? settings2 = _settings; if (settings2 != null && settings2.Settings.Launcher.EnableFileDialogIntegration) { WindowTracker.Capture(); _launcher.Show(); ((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)5, (Delegate)(Action)delegate { _launcher.SetInputText("cd "); }); } } }); }; _fileDialogWatcher.Start(); if (settings.Settings.Launcher.DockBarAutoShow) { ((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)6, (Delegate)(Action)delegate { ToggleDockBar(); }); } LogService.Info("초기화 완료. " + settings.Settings.Hotkey + "로 실행하세요."); } private void OnHotkeyTriggered(object? sender, EventArgs e) { WindowTracker.Capture(); LauncherSettings launcherSettings = _settings?.Settings.Launcher; bool flag = launcherSettings?.EnableTextAction ?? false; bool isVisible = false; ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { isVisible = _launcher?.IsVisible ?? false; }); if (isVisible) { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { _launcher?.Hide(); }); return; } if (!flag) { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { if (_launcher != null) { UsageStatisticsService.RecordLauncherOpen(); _launcher.Show(); } }); return; } string selectedText = TryGetSelectedText(); ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { if (_launcher != null) { if (!string.IsNullOrWhiteSpace(selectedText)) { List enabledCmds = launcherSettings?.TextActionCommands ?? new List(); if (enabledCmds.Count == 1 && !string.IsNullOrEmpty(TextActionPopup.AvailableCommands.FirstOrDefault<(string, string)>(((string Key, string Label) c) => c.Key == enabledCmds[0]).Item1)) { string text = enabledCmds[0]; if (1 == 0) { } TextActionPopup.ActionResult actionResult = text switch { "translate" => TextActionPopup.ActionResult.Translate, "summarize" => TextActionPopup.ActionResult.Summarize, "grammar" => TextActionPopup.ActionResult.GrammarFix, "explain" => TextActionPopup.ActionResult.Explain, "rewrite" => TextActionPopup.ActionResult.Rewrite, _ => TextActionPopup.ActionResult.None, }; if (1 == 0) { } TextActionPopup.ActionResult actionResult2 = actionResult; if (actionResult2 != TextActionPopup.ActionResult.None) { ExecuteTextAction(actionResult2, selectedText); return; } } TextActionPopup popup = new TextActionPopup(selectedText, enabledCmds); popup.Closed += delegate { switch (popup.SelectedAction) { case TextActionPopup.ActionResult.OpenLauncher: UsageStatisticsService.RecordLauncherOpen(); _launcher.Show(); break; case TextActionPopup.ActionResult.None: break; default: ExecuteTextAction(popup.SelectedAction, popup.SelectedText); break; } }; popup.Show(); } else { UsageStatisticsService.RecordLauncherOpen(); _launcher.Show(); } } }); } private string? TryGetSelectedText() { try { string prevText = null; bool hadText = false; ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { hadText = System.Windows.Clipboard.ContainsText(); prevText = (hadText ? System.Windows.Clipboard.GetText() : null); System.Windows.Clipboard.Clear(); }); Thread.Sleep(30); NativeMethods.INPUT[] array = new NativeMethods.INPUT[4] { new NativeMethods.INPUT { type = 1u, u = new NativeMethods.InputUnion { ki = new NativeMethods.KEYBDINPUT { wVk = 17 } } }, new NativeMethods.INPUT { type = 1u, u = new NativeMethods.InputUnion { ki = new NativeMethods.KEYBDINPUT { wVk = 67 } } }, new NativeMethods.INPUT { type = 1u, u = new NativeMethods.InputUnion { ki = new NativeMethods.KEYBDINPUT { wVk = 67, dwFlags = 2u } } }, new NativeMethods.INPUT { type = 1u, u = new NativeMethods.InputUnion { ki = new NativeMethods.KEYBDINPUT { wVk = 17, dwFlags = 2u } } } }; NativeMethods.SendInput((uint)array.Length, array, Marshal.SizeOf()); Thread.Sleep(80); string selected = null; ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { if (System.Windows.Clipboard.ContainsText()) { string text = System.Windows.Clipboard.GetText(); if (text != prevText && !string.IsNullOrWhiteSpace(text)) { selected = text; } } if (selected != null && prevText != null) { System.Windows.Clipboard.SetText(prevText); } else if (selected != null && !hadText) { System.Windows.Clipboard.Clear(); } }); return selected; } catch { return null; } } private void ExecuteTextAction(TextActionPopup.ActionResult action, string text) { if (1 == 0) { } string text2 = action switch { TextActionPopup.ActionResult.Translate => "다음 텍스트를 번역해줘:\n\n" + text, TextActionPopup.ActionResult.Summarize => "다음 텍스트를 요약해줘:\n\n" + text, TextActionPopup.ActionResult.GrammarFix => "다음 텍스트의 문법을 교정해줘:\n\n" + text, TextActionPopup.ActionResult.Explain => "다음 텍스트를 쉽게 설명해줘:\n\n" + text, TextActionPopup.ActionResult.Rewrite => "다음 텍스트를 다시 작성해줘:\n\n" + text, _ => text, }; if (1 == 0) { } string text3 = text2; _launcher?.Show(); _launcher?.SetInputText("! " + text3); } private void OnCaptureHotkeyTriggered(object? sender, EventArgs e) { WindowTracker.Capture(); string mode = _settings?.Settings.ScreenCapture.GlobalHotkeyMode ?? "screen"; ((DispatcherObject)this).Dispatcher.Invoke((Func)async delegate { if (_captureHandler == null) { return; } try { await _captureHandler.CaptureDirectAsync(mode); } catch (Exception ex) { LogService.Error("글로벌 캡처 실패: " + ex.Message); } }); } private void OnHookFailed(object? sender, EventArgs e) { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { _trayIcon?.ShowBalloonTip(3000, "AX Copilot", "글로벌 단축키 등록에 실패했습니다.\n다른 앱과 " + (_settings?.Settings.Hotkey ?? "단축키") + "가 충돌하고 있을 수 있습니다.", ToolTipIcon.Warning); }); } private void SetupTrayIcon(PluginHost pluginHost, SettingsService settings) { _trayIcon = new NotifyIcon { Text = "AX Copilot", Visible = true, Icon = LoadAppIcon() }; _trayMenu = new TrayMenuWindow(); _trayMenu.AddItem("\ue7c5", "AX Commander 호출하기", delegate { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { _launcher?.Show(); }); }).AddItem("\ue8bd", "AX Agent 대화하기", delegate { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { OpenAiChat(); }); }, out Border aiTrayItem).AddItem("\ue8a7", "독 바 표시", delegate { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { ToggleDockBar(); }); }) .AddSeparator() .AddItem("\ue72c", "플러그인 재로드", delegate { pluginHost.Reload(); _trayIcon.ShowBalloonTip(2000, "AX Copilot", "플러그인이 재로드되었습니다.", ToolTipIcon.None); }) .AddItem("\ue838", "로그 폴더 열기", delegate { string arguments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "logs"); Process.Start(new ProcessStartInfo("explorer.exe", arguments) { UseShellExecute = true }); }) .AddItem("\ue9d9", "사용 통계", delegate { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { new StatisticsWindow().Show(); }); }) .AddItem("\ue736", "사용 가이드 문서보기", delegate { try { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { new GuideViewerWindow().Show(); }); } catch (Exception ex) { LogService.Error("사용 가이드 열기 실패: " + ex.Message); } }) .AddSeparator() .AddToggleItem("\ue82f", "Windows 시작 시 자동 실행", IsAutoStartEnabled(), delegate(bool isChecked) { SetAutoStart(isChecked); }, out Func _, out Action _) .AddSeparator() .AddItem("\ue713", "설정", delegate { ((DispatcherObject)this).Dispatcher.Invoke((Action)OpenSettings); }) .AddItem("\ue946", "개발 정보", delegate { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { new AboutWindow().Show(); }); }) .AddItem("\ue711", "종료", delegate { _inputListener?.Dispose(); _trayIcon?.Dispose(); Shutdown(); }); _trayMenu.Opening += delegate { aiTrayItem.Visibility = ((!settings.Settings.AiEnabled) ? Visibility.Collapsed : Visibility.Visible); }; _trayIcon.MouseClick += delegate(object? _, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { _launcher?.Show(); }); } else if (e.Button == MouseButtons.Right) { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { _trayMenu?.ShowWithUpdate(); }); } }; NotificationService.Initialize(delegate(string title, string msg) { ((DispatcherObject)this).Dispatcher.Invoke((Action)delegate { _trayIcon?.ShowBalloonTip(4000, title, msg, ToolTipIcon.None); }); }); } public void OpenSettingsFromChat() { ((DispatcherObject)this).Dispatcher.Invoke((Action)OpenSettings); } internal void PrewarmChatWindow() { if (_chatWindow == null && _settings != null) { _chatWindow = new ChatWindow(_settings); } } private void OpenAiChat() { if (_settings != null) { if (_chatWindow == null) { _chatWindow = new ChatWindow(_settings); } _chatWindow.Show(); _chatWindow.Activate(); } } public void ToggleDockBar() { if (_dockBar != null && _dockBar.IsVisible) { _dockBar.Hide(); return; } if (_dockBar == null) { _dockBar = new DockBarWindow(); _dockBar.OnQuickSearch = delegate(string query) { if (_launcher != null) { _launcher.Show(); _launcher.Activate(); if (!string.IsNullOrEmpty(query)) { ((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)5, (Delegate)(Action)delegate { _launcher.SetInputText(query); }); } } }; _dockBar.OnCapture = async delegate { WindowTracker.Capture(); if (_captureHandler != null) { await _captureHandler.CaptureDirectAsync("region"); } }; _dockBar.OnOpenAgent = delegate { if (_launcher != null) { _launcher.Show(); ((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)5, (Delegate)(Action)delegate { _launcher.SetInputText("!"); }); } }; } LauncherSettings launcherSettings = _settings?.Settings.Launcher; List itemKeys = launcherSettings?.DockBarItems ?? new List { "launcher", "clipboard", "capture", "agent", "clock", "cpu" }; _dockBar.BuildFromSettings(itemKeys); _dockBar.OnPositionChanged = delegate(double left, double top) { if (_settings != null) { _settings.Settings.Launcher.DockBarLeft = left; _settings.Settings.Launcher.DockBarTop = top; _settings.Save(); } }; _dockBar.Show(); _dockBar.ApplySettings(launcherSettings?.DockBarOpacity ?? 0.92, launcherSettings?.DockBarLeft ?? (-1.0), launcherSettings?.DockBarTop ?? (-1.0), launcherSettings?.DockBarRainbowGlow ?? false); } public void RefreshDockBar() { if (_dockBar != null && _dockBar.IsVisible) { LauncherSettings launcherSettings = _settings?.Settings.Launcher; List itemKeys = launcherSettings?.DockBarItems ?? new List { "launcher", "clipboard", "capture", "agent", "clock", "cpu" }; _dockBar.BuildFromSettings(itemKeys); _dockBar.ApplySettings(launcherSettings?.DockBarOpacity ?? 0.92, launcherSettings?.DockBarLeft ?? (-1.0), launcherSettings?.DockBarTop ?? (-1.0), launcherSettings?.DockBarRainbowGlow ?? false); } } private void OpenSettings() { SettingsViewModel vm; if (_settingsWindow != null && _settingsWindow.IsVisible) { _settingsWindow.Activate(); } else { if (_settings == null || _launcher == null) { return; } vm = new SettingsViewModel(_settings); _settingsWindow = new SettingsWindow(vm, PreviewCallback, RevertCallback) { SuspendHotkeyCallback = delegate(bool suspend) { if (_inputListener != null) { _inputListener.SuspendHotkey = suspend; } } }; vm.SaveCompleted += delegate { if (_inputListener != null && _settings != null) { _inputListener.UpdateHotkey(_settings.Settings.Hotkey); _inputListener.UpdateCaptureHotkey(_settings.Settings.ScreenCapture.GlobalHotkey, _settings.Settings.ScreenCapture.GlobalHotkeyEnabled); } _worktimeReminder?.RestartTimer(); }; _settingsWindow.Show(); } void PreviewCallback(string themeKey) { if (themeKey == "custom") { CustomThemeColors customThemeColors = new CustomThemeColors(); foreach (ColorRowModel colorRow in vm.ColorRows) { typeof(CustomThemeColors).GetProperty(colorRow.Property)?.SetValue(customThemeColors, colorRow.Hex); } _launcher.ApplyTheme(themeKey, customThemeColors); } else { _launcher.ApplyTheme(themeKey, _settings.Settings.Launcher.CustomTheme); } } void RevertCallback() { _launcher.ApplyTheme(_settings.Settings.Launcher.Theme ?? "system", _settings.Settings.Launcher.CustomTheme); } } private static Icon LoadAppIcon() { Size smallIconSize = SystemInformation.SmallIconSize; try { string path = Path.GetDirectoryName(Environment.ProcessPath) ?? AppContext.BaseDirectory; string text = Path.Combine(path, "Assets", "icon.ico"); if (File.Exists(text)) { return new Icon(text, smallIconSize); } } catch { } try { Uri uriResource = new Uri("pack://application:,,,/Assets/icon.ico"); Stream stream = System.Windows.Application.GetResourceStream(uriResource)?.Stream; if (stream != null) { return new Icon(stream, smallIconSize); } } catch { } return SystemIcons.Application; } private static bool IsAutoStartEnabled() { try { using RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", writable: false); return registryKey?.GetValue("AxCopilot") != null; } catch { return false; } } private static void SetAutoStart(bool enable) { try { using RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", writable: true); if (registryKey == null) { return; } if (enable) { string text = Environment.ProcessPath ?? Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty; if (!string.IsNullOrEmpty(text)) { registryKey.SetValue("AxCopilot", "\"" + text + "\""); } } else { registryKey.DeleteValue("AxCopilot", throwOnMissingValue: false); } } catch (Exception ex) { LogService.Warn("자동 시작 레지스트리 설정 실패: " + ex.Message); } } protected override void OnExit(ExitEventArgs e) { _chatWindow?.ForceClose(); _inputListener?.Dispose(); _clipboardHistory?.Dispose(); _indexService?.Dispose(); _sessionTracking?.Dispose(); _worktimeReminder?.Dispose(); _trayIcon?.Dispose(); try { _singleInstanceMutex?.ReleaseMutex(); } catch { } _singleInstanceMutex?.Dispose(); LogService.Info("=== AX Copilot 종료 ==="); base.OnExit(e); } [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "10.0.5.0")] public void InitializeComponent() { if (!_contentLoaded) { _contentLoaded = true; Uri resourceLocator = new Uri("/AxCopilot;component/app.xaml", UriKind.Relative); System.Windows.Application.LoadComponent(this, resourceLocator); } } [STAThread] [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "10.0.5.0")] public static void Main() { App app = new App(); app.InitializeComponent(); app.Run(); } }