使用 0 个参数调用 .ctor 时出现异常:为具有 CLSID {ID} 的组件检索 COM class 工厂失败。 HRESULT:0x80070005(E_ACCESSDENIED)

Exception calling .ctor with 0 arguments: Retrieving the COM class factory for component with CLSID {ID} failed. HRESULT: 0x80070005 (E_ACCESSDENIED)

在 powershell 5.1 (x86) 运行ning 中以不同用户身份使用 Interop.DSOFile.dll 函数和 类 时收到此错误。我使用的帐户是一个 AD 功能帐户,对包含 dll 的文件夹具有完全权限。我需要使用此帐户,因为它比我自己的 AD 帐户具有更多访问权限来完成所需的工作。

我能够运行在我自己的用户帐户上使用以下代码没有问题,但是当尝试使用功能帐户时,我在标题中收到错误。

[System.Reflection.Assembly]::LoadFrom('C:\Path\To\Interop.DSOFile.dll')

New-Object DSOFile.OleDocumentPropertiesClass

导致错误:

New-Object : Exception calling ".ctor" with "0" argument(s): "Retrieving the COM class factory for component with CLSID {58968145-CF05-4341-995F-2EE093F6ABA3} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))." At line:1 char:1 + New-Object DSOFile.OleDocumentPropertiesClass + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvoca tionException + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.Power Shell.Commands.NewObjectCommand

我检查了 CLSID 是否存在,我可以使用功能帐户看到它,它就在那里:

gci 'HKLM:\SOFTWARE\Classes\CLSID' | ?{$_.PSChildName -match '58968145-CF05-4341-995F-2EE093F6ABA3'}

Property      : {(default)}
PSPath        : 
Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE
            \Classes\CLSID\{58968145-CF05-4341-995F-2EE093F6ABA3}
PSParentPath  : 
Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE
            \Classes\CLSID
PSChildName   : {58968145-CF05-4341-995F-2EE093F6ABA3}
PSDrive       : HKLM
PSProvider    : Microsoft.PowerShell.Core\Registry
PSIsContainer : True
SubKeyCount   : 2
View          : Default
Handle        : Microsoft.Win32.SafeHandles.SafeRegistryHandle
ValueCount    : 1
Name          : HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{58968145-CF05-4341-9
            95F-2EE093F6ABA3}

我尝试使用来自类似 Whosebug 问题的解决方案,这些问题引用了使用 Dcomcnfg。exe\DCOM 配置来授予帐户访问权限。 Com+ 配置

我也将 AD 功能帐户添加到我的本地管理员组,但没有成功。

感谢 Lieven Keersmaeker's procmon 调试建议,我得以解决问题。

正在解析的已注册 dll 位于我的旧 AD 帐户文件夹下的加密文件夹中(我的 AD sAMAccount 最近已更改)。我在注册表中找到了 dll,将路径更改为该 dll 的更易于访问的副本,并且它完美运行!

在此之前我不知道如何正确调试这个问题,也不知道 windows 是如何解析 dll 的。我假设如果 dll(在本例中为 dsofile.dll)与 Interop.DSOFile.dll 位于同一目录中,那么它将解析同一目录中的文件,而不是访问注册表。我现在更清楚了。