COMException 未知错误 (0x80005000) - DirectoryServices

Posted

技术标签:

【中文标题】COMException 未知错误 (0x80005000) - DirectoryServices【英文标题】:COMException Unknown error (0x80005000) - DirectoryServices 【发布时间】:2014-04-11 13:15:50 【问题描述】:

我在一个应用程序中遇到了一个错误,该错误每月发生几次,但本周又发生了两次。发生这种情况时,总是在早上第一个用户加载应用程序并开始工作(Web 应用程序,3-4 个内部用户)的第一件事。错误源于这个非常简单的方法,一旦失败,直到我重新启动应用程序池。现在,我也在以其他方式查询 AD,但这是用户早上开始工作时调用的第一个 AD 相关方法。

public DomainUser GetDomainUser(string userLoginName)
    
        using (PrincipalContext context = new PrincipalContext(ContextType.Domain, this.DomainName))
        
            using (UserPrincipal user = UserPrincipal.FindByIdentity(context, userLoginName))
            
                // If user is null, the result is not a UserPrinciple
                if (user != null)
                
                    string firstName = user.GivenName;
                    string middleName = user.MiddleName;
                    string lastName = user.Surname;
                    int empId = Convert.ToInt32(user.EmployeeId);
                    string emailAddr = user.EmailAddress;
                    string userName = user.SamAccountName;
                    DateTime? accountExp = user.AccountExpirationDate;

                    return new DomainUser
                    
                        FirstName = firstName,
                        MiddleName = middleName,
                        LastName = lastName,
                        EmployeeId = empId,
                        Email = emailAddr,
                        UserName = userName,
                        AccountExpiration = accountExp
                    ;
                

                return null;
            
        
    

所以this 问题密切相关,但我的权限设置正确,代码 99% 的时间都可以运行,并且在应用程序池重新启动后将继续运行。

堆栈跟踪看起来像这样:

System.Runtime.InteropServices.COMException (0x80005000): Unknown error (0x80005000)
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.PropertyValueCollection.PopulateList()
   at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
   at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
   at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, String identityValue)
   at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, String identityValue)
   at ADWrapper.AdSearch.GetDomainUser(String userLoginName)

可能是什么问题?内存泄漏?常见的模式是,当第一个用户开始使用应用程序时,这会发生在早上的第一件事。

【问题讨论】:

如果我是你,我会在 finally 子句中处理对象,以确保 ^^ 因为可能会发生错误,并生成未处理的对象。遇到此错误时,您是否也尝试使用 Thread.Sleep ? AD 可能会在响应和产生问题之前使用毫秒。 即使发生异常,using语句不应该处理这个吗? 取决于对象:***.com/questions/149609/c-sharp-using-syntax。此外,在您的情况下,您应该与其他人分开管理 COMException 。我的意见;) 感谢您的评论。单独管理 COMException 是什么意思?在这种情况下,我相信除非发生电源故障之类的事情(此时,我不在乎),否则可以保证处置。 @Rafi 不,我从未找到真正的解决方案,但我相信这是由于内存泄漏造成的。我想不出任何其他可以解释错误的时间和随机性的东西。每当大量使用这些方法时,这个问题就会很痛苦。对我来说,这大约是一个月两次。因为这是一个小的内部应用程序,我只是重新启动应用程序池。我可能会避免 System.DirectoryServices.AccountManagment 大量使用,并采用手动创建 ldap 搜索查询的旧方法,如下所示:***.com/a/1884855/1368050 【参考方案1】:

我们遇到了类似的问题。这是微软提供的解决方案。我希望这对某人有所帮助。

DirectoryEntry.Bind 函数最终调用 ADsOpenObject (https://docs.microsoft.com/en-us/windows/win32/api/adshlp/nf-adshlp-adsopenobject) 这个功能有一个“路由器”。路由器的初始化从注册表中枚举提供者,例如“LdapNamespace”。它位于 HKEY_CLASSES_ROOT\CLSID228D9A82-C302-11cf-9AA4-00AA004A5691\ProgID。 其他提供者,如 WinNT 命名空间也被枚举。

在跟踪中,查找这些注册表项时会返回错误。错误是,

ERROR_KEY_DELETED

1018 (0x3FA)

尝试对已标记为删除的注册表项进行非法操作。

此错误可能是由于卸载了进程用于其身份的用户配置文件。

Windows 用户配置文件服务强制卸载用户配置文件。这会导致流程出现问题。

我在 w3wp.exe 和 dllhost.exe 中看到了这一点,其中注册表配置文件在进程完成之前被卸载。

这是我们针对 dllhost.exe 的问题撰写的博客:https://blogs.msdn.microsoft.com/distributedservices/2009/11/06/a-com-application-may-stop-working-on-windows-server-2008-when-the-identity-user-logs-off/

您可能会在应用程序日志中看到警告,其描述如下: Windows 检测到您的注册表文件仍在被其他应用程序或服务使用。现在将卸载该文件。保存您的注册表文件的应用程序或服务之后可能无法正常运行。

我认为我们应该尝试博客中的解决方案/解决方法:

分辨率

作为一种解决方法,可能需要禁用此功能,这是默认行为。策略设置“不要在用户注销时强制卸载用户注册表”会阻止 Windows 2008 的默认行为。启用后,Windows 2008 不会强制卸载注册表,并等到没有其他进程正在使用用户注册表后再卸载它。

可以在组策略编辑器 (gpedit.msc) 中找到该策略

计算机配置->管理模板->系统->用户配置文件

不要在用户注销时强制卸载用户注册表

将设置从“未配置”更改为“启用”,这将禁用新的用户配置文件服务功能。

此更改不应有任何副作用。

【讨论】:

【参考方案2】:

很长一段时间以来,我一直在为同样的问题苦苦挣扎。我的解决方案实际上是安装功能 IIS 6 Metabase Compatblity。之后就没有问题了。下面是一些对我有帮助的文章

http://blogs.msdn.com/b/jpsanders/archive/2009/05/13/iis-7-adsi-error-system-runtime-interopservices-comexception-0x80005000-unknown-error-0x80005000.aspx

http://michaelwasham.com/2011/04/25/annoying-error-using-system-directoryservices-and-iis-app-pools/

【讨论】:

以上是关于COMException 未知错误 (0x80005000) - DirectoryServices的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 COMException 错误 80040154?

仅在 VS 2010 上运行时:COMException:灾难性故障:错误代码:-2147418113

IMAPI:COMException 发生内部文件系统错误 [-1062555360]

尝试在 C# 中使用 ActiveX 控件加载 PDF 文件时出现 COMException 错误

通过 COM 读取 Office PPT 文件提示 COMException 错误码 0x80004005 可能原因

尝试运行“应用程序一直在停止”的应用程序时遇到以下错误如何解决?