Windows10下CoCreateInstance报错0x80131700,无需安装.NET3.5的解决方法求助
问题核心原因
你当前配置不生效的根本原因是:.NET运行时配置文件是和启动进程(也就是你的32位C++遗留宿主程序)绑定的,而非和被加载的COM程序集绑定。你给.NET程序集添加的*.dll.config文件在COM激活场景下不会被读取,系统依然会按照默认逻辑查找.NET 2.0运行时,因此触发安装.NET 3.5的提示。错误码0x80131700对应的是CLR_E_SHIM_RUNTIMELOAD,本质就是找不到符合要求的.NET运行时版本。
可行解决方案
按实现成本从低到高排序:
方案1:给C++宿主程序添加配置文件
假设你的C++遗留应用程序名为LegacyApp.exe,在同目录下新建LegacyApp.exe.config,内容和你之前写的配置完全一致即可:<?xml version="1.0" encoding="utf-8"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> <supportedRuntime version="v2.0.50727"/> </startup> </configuration>该方案不需要修改任何代码,是首选方案。
方案2:重新编译.NET程序集面向.NET Framework 4.x
如果不方便修改宿主侧的配置,你可以将原来面向.NET 2.0的C#程序集,调整目标框架为.NET Framework 4.0/4.8,保留COM互操作的配置重新编译。只要你的代码没有使用.NET 4.x中已废弃的.NET 2.0专属API,基本可以无缝兼容,重新编译后的程序集激活时会直接绑定.NET 4.8运行时,不需要依赖.NET 3.5。
注意重新注册COM时要使用32位版本的.NET 4.x regasm工具,路径为C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe,避免注册到64位注册表路径导致加载失败。方案3:修改C++代码手动指定.NET运行时加载
如果你可以调整C++端的加载逻辑,可以放弃默认的CoCreateInstance激活逻辑,手动枚举并加载.NET 4.0运行时后再创建COM对象,从根源上避免触发.NET 2.0的查找逻辑,示例代码片段如下:#include <metahost.h> #pragma comment(lib, "mscoree.lib") ICLRMetaHost* pMetaHost = nullptr; ICLRRuntimeInfo* pRuntimeInfo = nullptr; ICLRRuntimeHost* pRuntimeHost = nullptr; // 初始化CLR元主机 HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost)); if (FAILED(hr)) goto Cleanup; // 获取.NET 4.0运行时实例 hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)); if (FAILED(hr)) goto Cleanup; // 检查运行时是否可加载 BOOL isLoadable = FALSE; hr = pRuntimeInfo->IsLoadable(&isLoadable); if (FAILED(hr) || !isLoadable) goto Cleanup; // 启动运行时 hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pRuntimeHost)); if (FAILED(hr)) goto Cleanup; hr = pRuntimeHost->Start(); if (FAILED(hr)) goto Cleanup; // 后续再执行原来的CoCreateInstance逻辑即可正常加载.NET 2.0程序集该方案不依赖配置文件,兼容性最高。
内容的提问来源于stack exchange,提问作者Fabius Wiesner

