zoukankan      html  css  js  c++  java
  • CLR 运行时版本和错误0x80131700和0x80113101B

    COM可见的.Net对象由标准COM调用实例化,例如CoCreateInstance。COM在注册表或激活上下文中找到CLSID,加载并调用mscoree.dll,该dll继续激活CLR和创建对象的过程。在此过程中,可能会出现错误0x80131700“未能加载运行时”或0x8013101b“此程序集是由比当前加载的运行时更新的运行时生成的,无法加载”。
    这两条消息都是运行时版本不匹配的结果。0x80131700并不一定意味着任何损坏,它只是意味着无法加载运行时。可能是因为未安装,或者未安装所需的版本。0x8013101b表示加载了运行时,但结果与继续处理所需的版本不匹配。
    让我们考虑Manifest Maker附带的Visual Studio示例。这里的本机主机程序是cmdEXE.exe,.Net对象是在clrDLL.dll中实现的。在本例中,我们重建了项目,而没有在DLL中嵌入CLR清单。因此,我们在子文件夹clrDLLclrDLL.DLL中有clrDLL.manifest文件和DLL。当我们现在执行“cmdEXE.exe clr”时,程序使用CoCreateInstance实例化clr对象:

    clrDLL::IClrSampleClassPtr scp;
       HRESULT hr = scp.CreateInstance(__uuidof(clrDLL::ClrSampleClass), nullptr, CLSCTX_INPROC_SERVER);
       if (S_OK != hr)
       {
          wprintf(L"
    CLR class instantiation failed, hresult = 0x%08X
    ", hr);
          return hr;
       }

    clrDLL.manifest 包含下面的条目 :

    <clrClass
       name="clrDLL.ClrSampleClass"
       clsid="{A1B62C33-E218-469D-81C4-10D4F2C608F7}"
       progid="clrDLL.ClrSampleClass"
       threadingModel="Both"/>

    事件的顺序如下:

    • 我们运行“cmdEXE.exe clr”
    • CSRSS创建进程,查找应用程序清单并创建包含clrDLL.manifest的激活上下文。
    • 程序调用COM来创建对象。
    • COM在激活上下文中找到CLSID,注意这是<clrClass>,加载并调用mscoree.dll。
    • mscoree.dll加载实际的.Net运行时并初始化它。
    • 运行时(当前为mscoreei.dll)从system和cmdEXE.exe.config读取配置
    • 运行时创建请求的对象。

    流程监视器日志摘录:

    1:38:32.0379228 PM csrss.exe   500 ReadFile C:ProjectsExamples.2vs2015\_Debug-Win32clrDLL.Manifest
    1:38:32.0913937 PM cmdEXE.exe 3320 Load Image C:WindowsSysWOW64mscoree.dll
    1:38:32.0980055 PM cmdEXE.exe 3320 Load Image C:WindowsMicrosoft.NETFrameworkv4.0.30319mscoreei.dll
    1:38:32.1078790 PM cmdEXE.exe 3320 CreateFile C:ProjectsExamples.2vs2015\_Debug-Win32cmdEXE.exe.config

    从上面可以看出,虽然mscoree决定加载哪个版本的.Net运行时,但它没有cmdEXE.exe.config的内容。这意味着此文件无助于解决任何运行时版本问题。处理此文件时,运行时已加载。
    如果如上所示编写<clrClass>,mscoree将决定(在Windows 7/8/8.1上)该类需要.Net 2.0,并尝试加载此版本的运行时。如果此计算机没有.Net 2.0,调用将失败,并出现错误0x80131700,在Windows 8上,将显示一个对话框,其中包含安装.Net 2.0的选项:

    如果runtime is 2.0可用并已加载,但DLL是用4.0构建的,则会出现错误0x8013101b。因此无法成功实例化如上所示定义的.Net类。必须修改<clrClass>条目以包含“runtimeVersion”属性:

    <clrClass
       name="clrDLL.ClrSampleClass"
       clsid="{A1B62C33-E218-469D-81C4-10D4F2C608F7}"
       progid="clrDLL.ClrSampleClass"
       runtimeVersion="v4.0.30319"
       threadingModel="Both"/>

    注意“runtimeVersion”与supportedRuntime不同。Net期望“supportedRuntime”包含“v4.0”,而“runtime version”必须包含实际的、完整的运行时版本。这意味着要选择.Net 4.0运行时,必须指定runtimeVersion=“v4.0.30319”。在编写本文时,存在以下运行时版本:

    • v1.0.3705
    • v1.1.4322
    • v2.0.50727
    • v4.0.30319

    另外.Net似乎接受“v3.0”和“v3.5”作为版本2.0的别名。确定实际版本号的一种快速方法是查看C: WindowsMicrosoft.NETFramework和C: WindowsMicrosoft.NETFramework64文件夹中的子文件夹名称。找到已安装版本的最终方法是运行以下代码:

    ICLRMetaHost *pMetaHost;
       HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (void **)&pMetaHost);
    
       IEnumUnknown* pEnum = 0;
       if (S_OK == pMetaHost->EnumerateInstalledRuntimes(&pEnum))
       {
          ULONG celt = 0;
          ICLRRuntimeInfo *pRuntime;
          while (S_OK == pEnum->Next(1, (IUnknown**)&pRuntime, &celt))
          {
             WCHAR version[256] = { 0 };
             DWORD chars = _countof(version);
             if (S_OK == pRuntime->GetVersionString(version, &chars))
                wprintf(L"Found: %s
    ", version);
             pRuntime->Release();
          }
          pEnum->Release();
       }

    清单生成器使用此技术填充“项目选项”对话框中的“CLR版本”属性页。健全性检查:Windows正在缓存每个程序的清单信息。如果您正在尝试清单,则必须更改每个参与文件(包括可执行文件)的时间戳,以使Windows使用新的而不是缓存的信息。

  • 相关阅读:
    Java中的BoneCP数据库连接池用法
    css 属性选择器笔记
    px,em,rem的区别
    谈谈newDate()的简单使用 JS
    user-select属性用法
    闭包解决的问题
    jQuery 中position()与offset()的区别
    attr() VS prop()
    .toArray()与jQuery.makeArray()的区别
    浏览器的缓存控制
  • 原文地址:https://www.cnblogs.com/yilang/p/12426213.html
Copyright © 2011-2022 走看看