public static void JumpRegEdit(string regPath, string valueName = null, bool moreOpen = false) { IntPtr hMain = FindWindow("RegEdit_RegEdit", null); if (moreOpen || hMain == IntPtr.Zero) { using (Process process = Process.Start("regedit.exe", "-m")) { process.WaitForInputIdle(); hMain = process.MainWindowHandle; } } IntPtr hTree = FindWindowEx(hMain, IntPtr.Zero, "SysTreeView32", null); IntPtr hList = FindWindowEx(hMain, IntPtr.Zero, "SysListView32", null); SetForegroundWindow(hTree); SetFocus(hTree); SendMessage(hTree, WM_KEYDOWN, VK_HOME, null); Thread.Sleep(50); SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null); foreach (char chr in Encoding.Default.GetBytes(regPath)) { if (chr == '\\') { Thread.Sleep(50); SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null); } else { SendMessage(hTree, WM_CHAR, Convert.ToInt16(chr), null); } } if (string.IsNullOrEmpty(valueName)) { return; } using (RegistryKey key = RegistryEx.GetRegistryKey(regPath)) { if (key?.GetValue(valueName) == null) { return; } } Thread.Sleep(50); SetForegroundWindow(hList); SetFocus(hList); SendMessage(hList, WM_KEYDOWN, VK_HOME, null); foreach (char chr in Encoding.Default.GetBytes(valueName)) { SendMessage(hList, WM_CHAR, Convert.ToInt16(chr), null); } }
/// <summary>获取注册表项及其子项、递归子级子项权限</summary> /// <remarks>将注册表项所有者改为当前管理员用户</remarks> /// <param name="regPath">要获取权限的注册表完整路径</param> public static void TakeRegTreeOwnerShip(string regPath) { if (regPath.IsNullOrWhiteSpace()) { return; } TakeRegKeyOwnerShip(regPath); using (RegistryKey key = RegistryEx.GetRegistryKey(regPath)) if (key != null) { foreach (string subKeyName in key.GetSubKeyNames()) { TakeRegTreeOwnerShip($@"{key.Name}\{subKeyName}"); } } }
/// <summary>判断文件或文件夹或注册表项是否存在</summary> /// <param name="path">文件或文件夹或注册表项路径</param> /// <param name="type">路径类型</param> /// <returns>目标路径存在返回true,否则返回false</returns> public static bool ObjectPathExist(string path, PathType type) { switch (type) { case PathType.File: return(File.Exists(path)); case PathType.Directory: return(Directory.Exists(path)); case PathType.Registry: return(RegistryEx.GetRegistryKey(path) != null); default: return(false); } }
/// <summary>获取带序号的新路径</summary> /// <param name="oldPath">目标路径</param> /// <param name="type">路径类型</param> /// <returns>如果目标路径不存在则返回目标路径,否则返回带序号的新路径</returns> public static string GetNewPathWithIndex(string oldPath, PathType type, int startIndex = -1) { string newPath; string dirPath = type == PathType.Registry ? RegistryEx.GetParentPath(oldPath) : Path.GetDirectoryName(oldPath); string name = type == PathType.Registry ? RegistryEx.GetKeyName(oldPath) : Path.GetFileNameWithoutExtension(oldPath); string extension = type == PathType.Registry ? "" : Path.GetExtension(oldPath); do { newPath = $@"{dirPath}\{name}"; if (startIndex > -1) { newPath += startIndex; } newPath += extension; startIndex++; } while(ObjectPathExist(newPath, type)); return(newPath); }
/// <summary>在Regedit中跳转指定路径并定位指定键名</summary> /// <param name="regPath">注册表项路径</param> /// <param name="valueName">注册表键名</param> /// <param name="moreOpen">窗口是否多开</param> public static void JumpRegEdit(string regPath, string valueName = null, bool moreOpen = false) { //还有一种方法,修改HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit //中的LastKey键值(记录上次关闭注册表编辑器时的注册表路径)为要跳转的注册表项路径regPath, //再使用Process.Start("regedit.exe", "-m")打开注册表编辑器 //优点:代码少、不会有Bug。缺点:不能定位具体键,没有逐步展开效果 if (regPath == null) { return; } Process process; IntPtr hMain = FindWindow("RegEdit_RegEdit", null); if (hMain != IntPtr.Zero && !moreOpen) { GetWindowThreadProcessId(hMain, out int id); process = Process.GetProcessById(id); } else { //注册表编辑器窗口多开 process = Process.Start("regedit.exe", "-m"); process.WaitForInputIdle(); hMain = process.MainWindowHandle; } ShowWindowAsync(hMain, SW_SHOWNORMAL); SetForegroundWindow(hMain); IntPtr hTree = FindWindowEx(hMain, IntPtr.Zero, "SysTreeView32", null); IntPtr hList = FindWindowEx(hMain, IntPtr.Zero, "SysListView32", null); SetForegroundWindow(hTree); SetFocus(hTree); process.WaitForInputIdle(); SendMessage(hTree, WM_KEYDOWN, VK_HOME, null); Thread.Sleep(100); process.WaitForInputIdle(); SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null); foreach (char chr in Encoding.Default.GetBytes(regPath)) { process.WaitForInputIdle(); if (chr == '\\') { Thread.Sleep(100); SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null); } else { SendMessage(hTree, WM_CHAR, Convert.ToInt16(chr), null); } } if (string.IsNullOrEmpty(valueName)) { return; } using (RegistryKey key = RegistryEx.GetRegistryKey(regPath)) { if (key?.GetValue(valueName) == null) { return; } } Thread.Sleep(100); SetForegroundWindow(hList); SetFocus(hList); process.WaitForInputIdle(); SendMessage(hList, WM_KEYDOWN, VK_HOME, null); foreach (char chr in Encoding.Default.GetBytes(valueName)) { process.WaitForInputIdle(); SendMessage(hList, WM_CHAR, Convert.ToInt16(chr), null); } process.Dispose(); }
/// <summary>获取注册表项权限</summary> /// <remarks>将注册表项所有者改为当前管理员用户</remarks> /// <param name="regPath">要获取权限的注册表完整路径</param> public static void TakeRegKeyOwnerShip(string regPath) { if (regPath.IsNullOrWhiteSpace()) { return; } RegistryKey key = null; WindowsIdentity id = null; //利用试错判断是否有写入权限 try { key = RegistryEx.GetRegistryKey(regPath, true); } catch { try { //获取当前用户的ID id = WindowsIdentity.GetCurrent(); //添加TakeOwnership特权 bool flag = NativeMethod.TrySetPrivilege(NativeMethod.TakeOwnership, true); if (!flag) { throw new PrivilegeNotHeldException(NativeMethod.TakeOwnership); } //添加恢复特权(必须这样做才能更改所有者) flag = NativeMethod.TrySetPrivilege(NativeMethod.Restore, true); if (!flag) { throw new PrivilegeNotHeldException(NativeMethod.Restore); } //打开没有权限的注册表路径 key = RegistryEx.GetRegistryKey(regPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership); RegistrySecurity security = key.GetAccessControl(AccessControlSections.All); //得到真正所有者 //IdentityReference oldId = security.GetOwner(typeof(SecurityIdentifier)); //SecurityIdentifier siTrustedInstaller = new SecurityIdentifier(oldId.ToString()); //使进程用户成为所有者 security.SetOwner(id.User); key.SetAccessControl(security); //添加完全控制 RegistryAccessRule fullAccess = new RegistryAccessRule(id.User, RegistryRights.FullControl, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow); security.AddAccessRule(fullAccess); key.SetAccessControl(security); //注册表操作(写入、删除) //key.SetValue("temp", "");//示例 //恢复原有所有者 //security.SetOwner(siTrustedInstaller); //key.SetAccessControl(security); //收回原有权利 //security.RemoveAccessRule(fullAccess); //key.SetAccessControl(security); ///得到真正所有者、注册表操作、恢复原有所有者、收回原有权利,这四部分在原文中没有被注释掉 ///但是如果保留这四部分,会在恢复原有所有者这一步抛出异常,提示没有权限, ///不过我发现经过上面的操作,虽然无法还原所有者权限,但是已经获取了注册表权限 ///即已经将TrustedInstaller权限更改为当前管理员用户权限,我要的目的已经达到了 } catch { } } finally { key?.Close(); id?.Dispose(); } }
public static void JumpRegEdit(string regPath, string valueName = null, bool moreOpen = false) { if (regPath == null) { return; } Process process; IntPtr hMain = FindWindow("RegEdit_RegEdit", null); if (hMain != IntPtr.Zero && !moreOpen) { GetWindowThreadProcessId(hMain, out int id); process = Process.GetProcessById(id); } else { process = Process.Start("regedit.exe", "-m"); process.WaitForInputIdle(); hMain = process.MainWindowHandle; } ShowWindowAsync(hMain, SW_SHOWNORMAL); SetForegroundWindow(hMain); IntPtr hTree = FindWindowEx(hMain, IntPtr.Zero, "SysTreeView32", null); IntPtr hList = FindWindowEx(hMain, IntPtr.Zero, "SysListView32", null); SetForegroundWindow(hTree); SetFocus(hTree); process.WaitForInputIdle(); SendMessage(hTree, WM_KEYDOWN, VK_HOME, null); Thread.Sleep(100); process.WaitForInputIdle(); SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null); foreach (char chr in Encoding.Default.GetBytes(regPath)) { process.WaitForInputIdle(); if (chr == '\\') { Thread.Sleep(100); SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null); } else { SendMessage(hTree, WM_CHAR, Convert.ToInt16(chr), null); } } if (string.IsNullOrEmpty(valueName)) { return; } using (RegistryKey key = RegistryEx.GetRegistryKey(regPath)) { if (key?.GetValue(valueName) == null) { return; } } Thread.Sleep(100); SetForegroundWindow(hList); SetFocus(hList); process.WaitForInputIdle(); SendMessage(hList, WM_KEYDOWN, VK_HOME, null); foreach (char chr in Encoding.Default.GetBytes(valueName)) { process.WaitForInputIdle(); SendMessage(hList, WM_CHAR, Convert.ToInt16(chr), null); } process.Dispose(); }