-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainWindow.xaml.cs
More file actions
256 lines (227 loc) · 8.14 KB
/
Copy pathMainWindow.xaml.cs
File metadata and controls
256 lines (227 loc) · 8.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using WinNetManager.Services;
using WinNetManager.Views;
namespace WinNetManager;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ThemeManager.ApplyTitleBar(this);
UpdateThemeButton();
ThemeManager.ThemeChanged += UpdateThemeButton;
// 连接名称变更后,需要刷新所有使用 InterfaceAlias 的标签页。
// 各标签页独立加载数据(Loaded 事件或手动刷新),没有共享数据源,
// 所以改名后如果不主动刷新,它们会继续显示内存中的旧名称。
ConnectionNameService.ConnectionsChanged += OnConnectionsChanged;
}
private void BtnTheme_Click(object sender, RoutedEventArgs e) => ThemeManager.Toggle();
private void UpdateThemeButton()
{
BtnTheme.Content = ThemeManager.IsDark ? "亮色" : "暗色";
BtnTheme.ToolTip = ThemeManager.IsDark ? "切换为亮色主题" : "切换为暗色主题";
}
private async void OnConnectionsChanged()
{
// Rename-NetAdapter 通知网络栈后,OS 内部传播需要短暂时间
await Task.Delay(500);
RefreshTab(DhcpTab);
RefreshTab(DnsTab);
RefreshTab(MetricTab);
RefreshTab(RouteTab);
}
private async void RefreshTab(UserControl tab)
{
if (tab is IRefreshableTab r)
await r.RefreshAsync();
}
public void SetStatus(string message)
{
StatusText.Text = message;
}
public void SetCommandPreview(string command)
{
TxtCommandPreview.Text = command;
CmdPreviewExpander.IsExpanded = true;
}
private void BtnNcpa_Click(object sender, RoutedEventArgs e)
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = "control.exe",
Arguments = "ncpa.cpl",
UseShellExecute = true
});
}
catch { }
}
private void BtnDevMgr_Click(object sender, RoutedEventArgs e)
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = "devmgmt.msc",
UseShellExecute = true
});
}
catch { }
}
private async void BtnBackup_Click(object sender, RoutedEventArgs e)
{
var dlg = new Microsoft.Win32.SaveFileDialog
{
Title = "选择注册表备份保存位置",
FileName = $"NetworkBackup_{DateTime.Now:yyyyMMdd_HHmmss}",
DefaultExt = ".reg",
Filter = "注册表文件 (*.reg)|*.reg",
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
};
if (dlg.ShowDialog(this) != true) return;
string dir = System.IO.Path.GetDirectoryName(dlg.FileName)!;
string baseName = System.IO.Path.GetFileNameWithoutExtension(dlg.FileName);
try
{
var results = await Task.Run(() =>
{
var r = new List<string>();
r.Add(RegistryBackupService.BackupKeyToPath(
@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList",
System.IO.Path.Combine(dir, $"{baseName}_NetworkList.reg")));
r.Add(RegistryBackupService.BackupKeyToPath(
@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}",
System.IO.Path.Combine(dir, $"{baseName}_NetworkControl.reg")));
return r;
});
CopyableMessageBox.Show($"备份完成,已保存到:\n\n{string.Join("\n", results)}", "备份完成",
MessageBoxImage.Information);
SetStatus($"备份完成 → {dir}");
}
catch (Exception ex)
{
CopyableMessageBox.Show($"备份失败:\n{ex.Message}", "错误",
MessageBoxImage.Error);
}
}
private void BtnFirewall_Click(object sender, RoutedEventArgs e)
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = "wf.msc",
UseShellExecute = true
});
}
catch { }
}
private void BtnHosts_Click(object sender, RoutedEventArgs e)
{
try
{
string hostsPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
"System32", "drivers", "etc", "hosts");
Process.Start(new ProcessStartInfo
{
FileName = "notepad.exe",
Arguments = $"\"{hostsPath}\"",
UseShellExecute = true
});
}
catch { }
}
private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
bool inTextInput = IsTextInputFocus();
if (e.KeyboardDevice.Modifiers == System.Windows.Input.ModifierKeys.Control)
{
switch (e.Key)
{
// 以下快捷键在文本框中仍允许触发
case System.Windows.Input.Key.R:
InvokeActiveTab("BtnRefresh_Click");
e.Handled = true;
break;
case System.Windows.Input.Key.I:
InvokeActiveTab("BtnInvertSelection_Click");
e.Handled = true;
break;
case System.Windows.Input.Key.N:
if (!TryInvokeMethod("BtnNew_Click"))
TryInvokeMethod("BtnAdd_Click");
e.Handled = true;
break;
case System.Windows.Input.Key.F:
FocusFilter();
e.Handled = true;
break;
// Ctrl+A 在文本框中保留给全选,不在文本框时触发表格全选
case System.Windows.Input.Key.A:
if (!inTextInput)
{
InvokeActiveTab("BtnSelectAll_Click");
e.Handled = true;
}
break;
}
}
else if (e.Key == System.Windows.Input.Key.Delete && !inTextInput)
{
InvokeActiveTab("BtnDelete_Click");
e.Handled = true;
}
else if (e.Key == System.Windows.Input.Key.F2 && !inTextInput)
{
if (!TryInvokeMethod("BtnEdit_Click"))
TryInvokeMethod("BtnRename_Click");
e.Handled = true;
}
}
private bool TryInvokeMethod(string methodName)
{
var active = TabControl.SelectedItem as TabItem;
if (active?.Content is not UserControl uc) return false;
var mi = uc.GetType().GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (mi == null) return false;
try
{
mi.Invoke(uc, new object[] { this, System.Windows.RoutedEventArgs.Empty });
return true;
}
catch { return false; }
}
private void InvokeActiveTab(string methodName)
{
TryInvokeMethod(methodName);
}
private void FocusFilter()
{
var active = TabControl.SelectedItem as TabItem;
if (active?.Content is not UserControl uc) return;
var filterBox = uc.FindName("TxtFilter") as System.Windows.Controls.TextBox;
if (filterBox != null)
{
filterBox.Focus();
filterBox.SelectAll();
}
}
private static bool IsTextInputFocus()
{
DependencyObject? current = System.Windows.Input.Keyboard.FocusedElement as DependencyObject;
while (current != null)
{
if (current is TextBox or PasswordBox)
return true;
if (current is ComboBox comboBox && comboBox.IsEditable)
return true;
current = VisualTreeHelper.GetParent(current) ?? LogicalTreeHelper.GetParent(current);
}
return false;
}
}