我一直在对我从不再在公司工作的另一位开发人员那里继承的一些代码进行故障排除,请参见下文,并且对于可能出现的问题已经没有想法了。可以多用一些眼睛看看这个,看看我可能错过了什么。
代码已经运行了一年多,直到迁移到不同AD域的新主机上。与旧主机一样,新主机是加入 AD 的 2016 服务器,我用于测试的 Windows 帐户是本地管理员帐户和域管理员帐户。我使用这两个帐户都收到了相同的错误消息。唯一想到的另一个区别是代码在旧主机上的 .NET Core 6 下运行,而现在在新主机上运行在 .NET Core 8 下。我还没有读过任何有关 .NET 更改的内容Core 8 会影响 Microsoft.Win32 库的使用。
此应用程序处理来自邮件服务器的日志文件并将其写入 SQL 数据库,因此这是其唯一的功能,因此 UAC 设置已关闭。该代码正在尝试在
HKLM\SOFTWARE\WOW6432Node
下创建一个注册表子项。
这是该代码的简化版本:
public class TestCase
{
private const string MYAPPROOTKEY = "SOFTWARE\\WOW6432Node\\MyApp";
public TestCase()
{
// Current Windows Acct is a member of Domain Administrators and
// it is a member of the local Administrator's Group
WindowsIdentity _WindowsIdentity = WindowsIdentity.GetCurrent();
RegistryKey _HKLM = Microsoft.Win32.Registry.LocalMachine;
RegistryKey _MyAppKey = OpenSubKey(_HKLM, MYAPPROOTKEY);
if (_MyAppKey is null)
{
RegistrySecurity _RegistrySecurity = CreateElevatedRegistryRule(_WindowsIdentity);
_HKLM.SetAccessControl(_RegistrySecurity);
// throws Exception: Attempted to perform an unauthorized operation.
RegistryKey _MyAppRootKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(MYAPPROOTKEY,
RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None);
// Throws exception: Access to the registry key
// 'HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MyApp'
// is denied.
}
}
private static RegistryKey OpenSubKey(RegistryKey p_RegistryKey, string p_SubKey)
{
RegistryKey _RegistryKey = null;
try
{
_RegistryKey = p_RegistryKey.OpenSubKey(p_SubKey, RegistryKeyPermissionCheck.ReadWriteSubTree,
RegistryRights.ReadKey
| RegistryRights.EnumerateSubKeys
| RegistryRights.QueryValues
| RegistryRights.ReadPermissions);
}
catch (System.Exception ex)
{
string _Msg = ex.Message;
System.Exception _ApplicationException = FormatExceptionMsg.PrepareApplicationException(MethodBase.GetCurrentMethod(), ex);
DebugLogger.Write(LogEventLevel.Error, _ApplicationException, _Msg);
SerilogConsoleLogger.Write(LogEventLevel.Error, _Msg);
}
return _RegistryKey;
}
private static RegistrySecurity CreateElevatedRegistryRule(WindowsIdentity p_WindowsIdentity)
{
RegistrySecurity _RegistrySecurity = null;
try
{
_RegistrySecurity = new RegistrySecurity();
_RegistrySecurity.AddAccessRule(new RegistryAccessRule(
p_WindowsIdentity.Owner,
RegistryRights.ReadKey
| RegistryRights.WriteKey
| RegistryRights.ReadPermissions
| RegistryRights.SetValue
| RegistryRights.CreateSubKey
| RegistryRights.Delete
| RegistryRights.EnumerateSubKeys
| RegistryRights.QueryValues,
InheritanceFlags.None,
PropagationFlags.None,
AccessControlType.Allow));
}
catch (System.Exception ex)
{
string _Msg = ex.Message;
System.Exception _ApplicationException = FormatExceptionMsg.PrepareApplicationException(MethodBase.GetCurrentMethod(), ex);
DebugLogger.Write(LogEventLevel.Error, _ApplicationException, _Msg);
SerilogConsoleLogger.Write(LogEventLevel.Error, _Msg);
}
return _RegistrySecurity;
}
}
代码在这些管理员帐户下执行的所有其他操作都工作正常,因此我开始研究用户帐户控制设置是否可能是问题所在。尽管我将UAC设置为最低值,但这并没有解决问题。但在检查 UAC 的注册表项时,有几个设置我不熟悉。我希望有人能澄清这些是否是问题所在。
UAC 的注册表设置可以在以下位置找到:
SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System
我不熟悉的设置和值可能是此异常的根源是:
FilterAdministratorToken = 0
EnableUIADesktopToggle = 0
ConsentPromptBehaviorAdmin = 0
ConsentPromptBehaviorUser = 3
EnableLUA = 1
预先感谢您的帮助。
我通过拆解原始开发人员代码并简化它来解决这个问题,再次证明,少即是多:
//RegistrySecurity _RegistrySecurity = CreateElevatedRegistryRule(_WindowsIdentity);
//_HKLM.SetAccessControl(_RegistrySecurity);
// threw Exception: Attempted to perform an unauthorized operation.
//RegistryKey _MyAppRootKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(MYAPPROOTKEY, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryOptions.None);
// Threw Access Denied exception,
// This code worked just fine.
RegistryKey _MyAppRootKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(MYAPPROOTKEY);