如何以管理员身份用PowerShell 7和C#修改/删除TrustedInstaller所有注册表项
处理TrustedInstaller所有的注册表项:PowerShell 7与C#实现方案
一、PowerShell 7 实现步骤
要修改/删除TrustedInstaller拥有的注册表项,需先启用系统特权、夺取所有权、赋予自身权限,再执行操作。以下是完整脚本:
# 目标注册表项路径(示例) $regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\some-default-item" # 1. 定义P/Invoke类型用于启用系统特权 Add-Type @" using System; using System.Runtime.InteropServices; public class AdvApi32 { [DllImport("advapi32.dll", SetLastError = true)] public static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, ref IntPtr TokenHandle); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref LUID lpLuid); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, uint BufferLength, IntPtr PreviousState, IntPtr ReturnLength); [StructLayout(LayoutKind.Sequential)] public struct LUID { public uint LowPart; public int HighPart; } [StructLayout(LayoutKind.Sequential)] public struct LUID_AND_ATTRIBUTES { public LUID Luid; public uint Attributes; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct TOKEN_PRIVILEGES { public uint PrivilegeCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public LUID_AND_ATTRIBUTES[] Privileges; } } public class Kernel32 { [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr hObject); } "@ # 2. 启用SE_RESTORE和SE_BACKUP特权(修改系统注册表必需) $privilegeNames = @("SeRestorePrivilege", "SeBackupPrivilege") foreach ($privName in $privilegeNames) { $tokenHandle = [IntPtr]::Zero try { if (-not [AdvApi32]::OpenProcessToken([System.Diagnostics.Process]::GetCurrentProcess().Handle, 0x0020, [ref]$tokenHandle)) { Write-Error "无法打开进程令牌: $([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error())" continue } $luid = [AdvApi32+LUID]::new() if (-not [AdvApi32]::LookupPrivilegeValue($null, $privName, [ref]$luid)) { Write-Error "无法查找特权: $([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error())" continue } $privileges = [AdvApi32+TOKEN_PRIVILEGES]::new() $privileges.PrivilegeCount = 1 $privileges.Privileges = @([AdvApi32+LUID_AND_ATTRIBUTES]::new()) $privileges.Privileges[0].Luid = $luid $privileges.Privileges[0].Attributes = 0x00000002 # SE_PRIVILEGE_ENABLED if (-not [AdvApi32]::AdjustTokenPrivileges($tokenHandle, $false, [ref]$privileges, 0, [IntPtr]::Zero, [IntPtr]::Zero)) { Write-Error "无法调整令牌特权: $([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error())" } } finally { if ($tokenHandle -ne [IntPtr]::Zero) { [Kernel32]::CloseHandle($tokenHandle) } } } # 3. 获取当前管理员用户,修改注册表项所有权 $currentAdmin = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name $acl = Get-Acl -Path $regPath $owner = New-Object System.Security.Principal.NTAccount($currentAdmin) $acl.SetOwner($owner) Set-Acl -Path $regPath -AclObject $acl # 4. 赋予当前管理员完全控制权限 $rule = New-Object System.Security.AccessControl.RegistryAccessRule( $currentAdmin, [System.Security.AccessControl.RegistryRights]::FullControl, [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow ) $acl.AddAccessRule($rule) Set-Acl -Path $regPath -AclObject $acl # 5. 删除注册表项(如需修改,替换为Set-Item等操作) Remove-Item -Path $regPath -Recurse -Force
注意事项
- 操作前必须备份目标注册表项,避免系统功能异常
- 部分核心系统项修改后可能导致Explorer崩溃,需提示用户确认风险
- 脚本需以管理员身份运行PowerShell 7
二、C# 实现步骤
C#需通过P/Invoke调用Windows API处理所有权和特权,.NET自带Registry类无法直接操作TrustedInstaller拥有的项。以下是完整实现:
using System; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; using Microsoft.Win32; public class RegistryTrustedInstallerHelper { // Windows API 常量 private const uint SE_PRIVILEGE_ENABLED = 0x00000002; private const int ERROR_SUCCESS = 0; private const uint REG_KEY_ALL_ACCESS = 0xF003F; private const int OWNER_SECURITY_INFORMATION = 0x00000001; private const uint SE_REGISTRY_KEY = 7; // P/Invoke 结构体 [StructLayout(LayoutKind.Sequential)] private struct LUID { public uint LowPart; public int HighPart; } [StructLayout(LayoutKind.Sequential)] private struct LUID_AND_ATTRIBUTES { public LUID Luid; public uint Attributes; } [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct TOKEN_PRIVILEGES { public uint PrivilegeCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public LUID_AND_ATTRIBUTES[] Privileges; } // P/Invoke 方法 [DllImport("advapi32.dll", SetLastError = true)] private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle); [DllImport("advapi32.dll", SetLastError = true)] private static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid); [DllImport("advapi32.dll", SetLastError = true)] private static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, uint BufferLength, IntPtr PreviousState, IntPtr ReturnLength); [DllImport("advapi32.dll", SetLastError = true)] private static extern uint SetNamedSecurityInfo(string pObjectName, uint ObjectType, uint SecurityInfo, IntPtr psidOwner, IntPtr psidGroup, IntPtr pDacl, IntPtr pSacl); [DllImport("advapi32.dll", SetLastError = true)] private static extern bool ConvertStringSidToSid(string StringSid, out IntPtr Sid); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool CloseHandle(IntPtr hObject); // 启用指定系统特权 private static bool EnablePrivilege(string privilegeName) { if (!OpenProcessToken(System.Diagnostics.Process.GetCurrentProcess().Handle, 0x0020, out IntPtr tokenHandle)) return false; bool result = false; try { if (!LookupPrivilegeValue(null, privilegeName, out LUID luid)) return false; TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES(); tp.PrivilegeCount = 1; tp.Privileges = new LUID_AND_ATTRIBUTES[1]; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; result = AdjustTokenPrivileges(tokenHandle, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); result &= Marshal.GetLastWin32Error() == ERROR_SUCCESS; } finally { CloseHandle(tokenHandle); } return result; } // 夺取所有权并修改/删除注册表项 public static bool TakeOwnershipAndModify(string registryPath) { // 启用必需特权 if (!EnablePrivilege("SeRestorePrivilege") || !EnablePrivilege("SeBackupPrivilege")) return false; // 获取当前管理员SID NTAccount currentAccount = new NTAccount(WindowsIdentity.GetCurrent().Name); SecurityIdentifier sid = (SecurityIdentifier)currentAccount.Translate(typeof(SecurityIdentifier)); if (!ConvertStringSidToSid(sid.Value, out IntPtr sidPtr)) return false; try { // 修改注册表项所有权为当前用户 uint securityResult = SetNamedSecurityInfo(registryPath, SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, sidPtr, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if (securityResult != ERROR_SUCCESS) return false; // 打开注册表项并赋予完全控制权限 using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registryPath, RegistryKeyPermissionCheck.ReadWriteSubTree, REG_KEY_ALL_ACCESS)) { if (key == null) return false; RegistrySecurity security = key.GetAccessControl(); RegistryAccessRule rule = new RegistryAccessRule( sid, RegistryRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow ); security.AddAccessRule(rule); key.SetAccessControl(security); // 执行删除操作(如需修改,替换为SetValue等逻辑) key.DeleteSubKeyTree("", true); } return true; } finally { Marshal.FreeHGlobal(sidPtr); } } } // 调用示例 class Program { static void Main(string[] args) { // 目标注册表项路径(示例) string targetPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\some-default-item"; bool success = RegistryTrustedInstallerHelper.TakeOwnershipAndModify(targetPath); Console.WriteLine(success ? "操作完成" : "操作失败"); } }
注意事项
- 程序必须以管理员权限运行
- 操作前务必备份注册表,防止破坏系统默认功能
- 部分受系统保护的注册表项即使夺取所有权也无法删除,需提前告知用户风险
内容的提问来源于stack exchange,提问作者fmotion1
相关产品推荐
相关产品推荐

