/// <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) { 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); int index = 0; do { newPath = $@"{dirPath}\{name}"; if (index > 0) { newPath += index; } newPath += extension; index++; } while(ObjectPathExist(newPath, type)); return(newPath); }
/// <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 (Exception) { 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 (Exception) { } } finally { key?.Close(); id?.Dispose(); } }