获取/设置注册表ACL“SeSecurityPrivilege”时出现C#随机exception

我已经得到一个完全随机的exception,我可以运行1000次相同的代码集(每个“运行”是程序的完整结束,因此从命令行开始作为自己的进程然后存在)并得到它失败一次,甚至150次。 我的意思是我可以一遍又一遍地回溯它,它会完全随机失败。

System.Security.AccessControl.PrivilegeNotHeldException: The process does not possess the 'SeSecurityPrivilege' privilege which is required for this operation. at System.Security.AccessControl.Win32.GetSecurityInfo(ResourceType resourceType, String name, SafeHandle handle, AccessControlSections accessControlSections, RawSecurityDescriptor& resultSd) at System.Security.AccessControl.NativeObjectSecurity.CreateInternal(ResourceType resourceType, Boolean isContainer, String name, SafeHandle handle, AccessControlSections includeSections, Boolean createByName, ExceptionFromErrorCode exceptionFromErrorCode, Object exceptionContext) at System.Security.AccessControl.RegistrySecurity..ctor(SafeRegistryHandle hKey, String name, AccessControlSections includeSections) at Microsoft.Win32.RegistryKey.GetAccessControl(AccessControlSections includeSections) 

调试时我无法让它失败,因此在尝试查看为什么它会随机决定失败时遇到问题。 由于它在(RegistryKey).GetAccessControl(AccessControlSections.All)方法中失败了,我对接下来要尝试的内容感到(RegistryKey).GetAccessControl(AccessControlSections.All)

此外,我正在循环遍历多个密钥,如果它决定在一个密钥上出现此权限exception,则它们都会在该过程中失败。

我正在从命令行运行(作为管理员,UACed),启动进程然后它存在。 从同一个命令行我再次启动进程,它会随机失败。

我正在加载用户配置单元并确保注册表权限被提升,除了这个随机错误之外它也能正常工作。

此外,问题出现在系统(psexec)和管理员帐户下的多台计算机上(始终在本地运行,而不是远程运行)。

我不认为系统帐户启用了SeSecurityPrivilege,或者是管理员。

而不是(RegistryKey).GetAccessControl(AccessControlSections.All) ,尝试: (RegistryKey).GetAccessControl(AccessControlSections.Access)

这仍然会给你错误吗? 但是,您将无法通过Access获取SACL。

编辑:我从pinvoke抓取一些代码来调整访问令牌中的权限,你需要管理员权限来做; 我为SeSecurityPrivilege修改了它,你应该能够使用(RegistryKey).GetAccessControl(AccessControlSections.All)现在没有任何错误“SetPriv();” 叫做。 我能够通过使用Process Hacker 2并在之前和之后检查令牌来validation它是否正常工作,它启用了SeSecuirtyPrivilege:

  [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); [DllImport("kernel32.dll", ExactSpelling = true)] internal static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct TokPriv1Luid { public int Count; public long Luid; public int Attr; } internal const int SE_PRIVILEGE_ENABLED = 0x00000002; internal const int TOKEN_QUERY = 0x00000008; internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; internal const string SeSecurity = "SeSecurityPrivilege"; private bool SetPriv() { try { bool retVal; TokPriv1Luid tp; IntPtr hproc = GetCurrentProcess(); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_ENABLED; retVal = LookupPrivilegeValue(null, SeSecurity, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } catch (Exception ex) { throw; return false; } }