using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Security.Principal; using System.ServiceProcess; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Threading; using JJServiceManager.Remote; using Forms = System.Windows.Forms; namespace JJServiceManager { /// 초기화면 public sealed class MainWindow : Window { private static readonly TimeSpan OpTimeout = TimeSpan.FromSeconds(60); private readonly AppSettings _settings; private readonly FrameworkElement _root; private readonly ObservableCollection _groups = new ObservableCollection(); private readonly HostGroup _local; private readonly LogPanel _log; private readonly LogWindowManager _logWindows; private readonly DispatcherTimer _statusTimer; private readonly RemoteServer _remoteServer; private readonly PassiveHub _passiveHub; private RemoteIndicatorWindow _indicator; private readonly Dictionary _viewers = new Dictionary(StringComparer.OrdinalIgnoreCase); private string _passiveKey = ""; private string _passiveListenKey = ""; private readonly TabControl _tabs; private readonly TabItem _tabAll; private readonly ComboBox _cmbAddTab; private readonly CheckBox _chkAll; private readonly TextBlock _txtCount, _txtLogHidden; private readonly ContentControl _ccLog; private readonly FrameworkElement _pnlShutdown; private readonly Dictionary _hostTabs = new Dictionary(StringComparer.OrdinalIgnoreCase); /// 원격 접속 허용 쪽에 넘겨줄 등록 서비스 목록 (다른 스레드에서 읽음) private volatile IReadOnlyList _servicesSnapshot = Array.Empty(); private string _serverKey = ""; private string _targetsKey = ""; private Forms.NotifyIcon _tray; private HotkeyManager _hotkey; private bool _exiting; private bool _refreshing; private bool _trayTipShown; private bool _modalOpen; public MainWindow(AppSettings settings) { _settings = settings; Title = "JJServiceManager - 서비스 관리" + AppInstance.TitleTag; FontFamily = new FontFamily("Malgun Gothic"); FontSize = 13; Background = Brushes2.Make("#F5F7F8"); MinWidth = 860; MinHeight = 560; AppIcon.Apply(this); RestoreWindowBounds(settings); _root = XamlLoader.LoadElement("MainWindow.xaml"); Content = _root; _tabs = _root.Find("tabHosts"); _tabAll = _root.Find("tabAll"); _cmbAddTab = _root.Find("cmbAddTab"); _chkAll = _root.Find("chkAll"); _txtCount = _root.Find("txtCount"); _txtLogHidden = _root.Find("txtLogHidden"); _ccLog = _root.Find("ccLog"); _pnlShutdown = _root.Find("pnlShutdown"); _log = new LogPanel { ShowTimestamp = true }; _ccLog.Content = _log; _logWindows = new LogWindowManager(() => _settings, SaveSettings, LogChoices); // 내 PC _local = new HostGroup { Id = HostGroup.LocalId, Title = $"내 PC ({Environment.MachineName})", EmptyText = "[추가] 버튼을 눌러 관리할 서비스를 등록하세요." }; foreach (var e in settings.Services) _local.Rows.Add(new ServiceRow(e, _local)); _local.Rows.CollectionChanged += (s, e) => UpdateCounts(); _groups.Add(_local); UpdateSnapshot(); _root.Find("icGroups").ItemsSource = _groups; _cmbAddTab.ItemsSource = _groups; _cmbAddTab.SelectionChanged += OnAddTabSelected; _tabs.SelectionChanged += (s, e) => { if (e.Source == _tabs) UpdateCounts(); }; // 상단 버튼 _root.Find