Skip to content

Commit 3dfc442

Browse files
committed
Refactor Regedit navigation for safer process handling
Refactored the logic for opening and navigating Regedit to ensure proper disposal of the Process object using a try/finally block. Moved all process and window interaction code inside the try block, and now only attempt value selection if the value exists. This improves resource management, robustness, and prevents potential process leaks.
1 parent 169d53e commit 3dfc442

File tree

1 file changed

+72
-66
lines changed

1 file changed

+72
-66
lines changed

ContextMenuManager/BluePointLilac.Methods/ExternalProgram.cs

Lines changed: 72 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -23,86 +23,92 @@ public static void JumpRegEdit(string regPath, string valueName = null, bool mor
2323
//再使用Process.Start("regedit.exe", "-m")打开注册表编辑器
2424
//优点:代码少、不会有Bug。缺点:不能定位具体键,没有逐步展开效果
2525
if (regPath == null) return;
26-
Process process;
27-
var hMain = FindWindow("RegEdit_RegEdit", null);
28-
if (hMain != IntPtr.Zero && !moreOpen)
29-
{
30-
GetWindowThreadProcessId(hMain, out var id);
31-
process = Process.GetProcessById(id);
32-
}
33-
else
26+
Process process = null;
27+
try
3428
{
35-
//注册表编辑器窗口多开
36-
process = Process.Start("regedit.exe", "-m");
37-
process.WaitForInputIdle();
38-
39-
// 等待主窗口句柄可用,最多等待5秒
40-
int retries = MAX_WINDOW_WAIT_RETRIES;
41-
while (retries-- > 0)
29+
var hMain = FindWindow("RegEdit_RegEdit", null);
30+
if (hMain != IntPtr.Zero && !moreOpen)
4231
{
43-
process.Refresh();
44-
hMain = process.MainWindowHandle;
45-
if (hMain != IntPtr.Zero) break;
46-
Thread.Sleep(100);
32+
GetWindowThreadProcessId(hMain, out var id);
33+
process = Process.GetProcessById(id);
4734
}
48-
49-
if (hMain == IntPtr.Zero) return;
50-
}
35+
else
36+
{
37+
//注册表编辑器窗口多开
38+
process = Process.Start("regedit.exe", "-m");
39+
process.WaitForInputIdle();
5140

52-
ShowWindowAsync(hMain, SW_SHOWNORMAL);
53-
SetForegroundWindow(hMain);
54-
55-
// 等待树视图和列表视图控件就绪,最多等待5秒
56-
IntPtr hTree = IntPtr.Zero;
57-
IntPtr hList = IntPtr.Zero;
58-
int retries2 = MAX_CHILD_WINDOW_WAIT_RETRIES;
59-
while (retries2-- > 0)
60-
{
61-
hTree = FindWindowEx(hMain, IntPtr.Zero, "SysTreeView32", null);
62-
hList = FindWindowEx(hMain, IntPtr.Zero, "SysListView32", null);
63-
if (hTree != IntPtr.Zero && hList != IntPtr.Zero) break;
64-
Thread.Sleep(100);
65-
}
66-
67-
if (hTree == IntPtr.Zero || hList == IntPtr.Zero) return;
41+
// 等待主窗口句柄可用,最多等待5秒
42+
int retries = MAX_WINDOW_WAIT_RETRIES;
43+
while (retries-- > 0)
44+
{
45+
process.Refresh();
46+
hMain = process.MainWindowHandle;
47+
if (hMain != IntPtr.Zero) break;
48+
Thread.Sleep(100);
49+
}
6850

69-
SetForegroundWindow(hTree);
70-
SetFocus(hTree);
71-
process.WaitForInputIdle();
72-
SendMessage(hTree, WM_KEYDOWN, VK_HOME, null);
73-
Thread.Sleep(100);
74-
process.WaitForInputIdle();
75-
SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);
76-
foreach (char chr in Encoding.Default.GetBytes(regPath))
77-
{
78-
process.WaitForInputIdle();
79-
if (chr == '\\')
51+
if (hMain == IntPtr.Zero) return;
52+
}
53+
54+
ShowWindowAsync(hMain, SW_SHOWNORMAL);
55+
SetForegroundWindow(hMain);
56+
57+
// 等待树视图和列表视图控件就绪,最多等待5秒
58+
IntPtr hTree = IntPtr.Zero;
59+
IntPtr hList = IntPtr.Zero;
60+
int retries2 = MAX_CHILD_WINDOW_WAIT_RETRIES;
61+
while (retries2-- > 0)
8062
{
63+
hTree = FindWindowEx(hMain, IntPtr.Zero, "SysTreeView32", null);
64+
hList = FindWindowEx(hMain, IntPtr.Zero, "SysListView32", null);
65+
if (hTree != IntPtr.Zero && hList != IntPtr.Zero) break;
8166
Thread.Sleep(100);
82-
SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);
8367
}
84-
else
68+
69+
if (hTree == IntPtr.Zero || hList == IntPtr.Zero) return;
70+
71+
SetForegroundWindow(hTree);
72+
SetFocus(hTree);
73+
process.WaitForInputIdle();
74+
SendMessage(hTree, WM_KEYDOWN, VK_HOME, null);
75+
Thread.Sleep(100);
76+
process.WaitForInputIdle();
77+
SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);
78+
foreach (char chr in Encoding.Default.GetBytes(regPath))
8579
{
86-
SendMessage(hTree, WM_CHAR, Convert.ToInt16(chr), null);
80+
process.WaitForInputIdle();
81+
if (chr == '\\')
82+
{
83+
Thread.Sleep(100);
84+
SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);
85+
}
86+
else
87+
{
88+
SendMessage(hTree, WM_CHAR, Convert.ToInt16(chr), null);
89+
}
8790
}
88-
}
8991

90-
if (string.IsNullOrEmpty(valueName)) return;
91-
using (var key = RegistryEx.GetRegistryKey(regPath))
92-
{
93-
if (key?.GetValue(valueName) == null) return;
92+
if (string.IsNullOrEmpty(valueName)) return;
93+
using (var key = RegistryEx.GetRegistryKey(regPath))
94+
{
95+
if (key?.GetValue(valueName) == null) return;
96+
}
97+
Thread.Sleep(100);
98+
SetForegroundWindow(hList);
99+
SetFocus(hList);
100+
process.WaitForInputIdle();
101+
SendMessage(hList, WM_KEYDOWN, VK_HOME, null);
102+
foreach (char chr in Encoding.Default.GetBytes(valueName))
103+
{
104+
process.WaitForInputIdle();
105+
SendMessage(hList, WM_CHAR, Convert.ToInt16(chr), null);
106+
}
94107
}
95-
Thread.Sleep(100);
96-
SetForegroundWindow(hList);
97-
SetFocus(hList);
98-
process.WaitForInputIdle();
99-
SendMessage(hList, WM_KEYDOWN, VK_HOME, null);
100-
foreach (char chr in Encoding.Default.GetBytes(valueName))
108+
finally
101109
{
102-
process.WaitForInputIdle();
103-
SendMessage(hList, WM_CHAR, Convert.ToInt16(chr), null);
110+
process?.Dispose();
104111
}
105-
process.Dispose();
106112
}
107113

108114
/// <summary>在Explorer中选中指定文件或文件夹</summary>

0 commit comments

Comments
 (0)