如何解决R6034错误,实现在WIN7以上版本通过LoadLibrary加载msvcr90.dll等DLL

xingyun86 2018-7-19 2541

如何解决R6034错误,实现在WIN7以上版本通过LoadLibrary加载msvcr90.dll等DLL

为什么VC编译的程序在不同系统上运行经常报错?

    在XP(SP2 ?)以前,安装VC运行时库时,安装包只会将各种DLL释放到system32目录并注册相关信息到注册表,这样LoadLibrary时加载这些DLL也不会出错,因为对于应用程序来说,当前只有一个对应的运行时库被注册到系统中,不存在多个不同版本的问题,但也很容易造成兼容性问题,如使用VS2008编译的程序,在仅安装了VS2005运行时库的系统中可能会出现崩溃错误。

 

不同版本运行时库带来的冲突

    假如一个VC2005编译的程序,一旦出现运行时库不匹配而导致运行错误,我们就需要安装匹配的VC2005运行时库到系统里就可以解决了.

    但是如果问题那么容易解决就好了,不过对于这种问题如何解决,痛苦的也是微软的码农。

    在上面VC2005程序问题的基础上,再扩展一下,假如同时又有一个VC2008编译的程序运行出现错误,这样我们又得安装VC2008的运行时库了,新的运行时库又会覆盖掉System32里的同名DLL,那么问题来了,原来的VC2005程序又无法运行了,崩溃!不可能每运行一次就安装一次运行时库把?

    所以,微软在新的补丁中提供了一个叫Side-By-Side的模块,也就是简称SXS,该模块最初应该不是为了解决以上问题的,只是顺带而已,SXS应该是为了解决混乱的.NET Framework而设计的。但是不管怎样,有了SXS,就可以在系统中同时安装各种不同版本的运行时库也不会有冲突了。

    既然系统中安装了不同版本的运行时库,那么程序怎么知道自己要使用的到底是VC2005还是VC2008的运行库呢?

 

微软如何设计SXS来解决不同运行环境所带来的兼容性问题的?

在XP sp3,以及Vista, WIN7,WIN8,WIN10 后,为了在系统中同时提供多种CPU平台和不同VS版本的运行时库来兼容不同的应用软件,微软做了大概下面3个改进,

1)PE文件自带依赖库签名信息

2)在C:\Windows\WinSxS中存放各种不同版本的运行时库

3)有了上面的2个改进,剩下的无非就是系统运行EXE文件或者加载DLL时,如何根据依赖库签名信息来正确加载相应的运行时库了。

以上就是系统的Side-By-Side(SXS)组件设计时所要实现的大体目标和功能了。

 

程序开发中如何让SXS的识别不同版本依赖库?

      在VS开发时,可在工具中设置manifest来指定当前程序的依赖库签名信息(运行时库名称,版本,如win32 x86 版本号 等等),manifest可以嵌入到资源中,也可以放在本地的xml格式的文本文件,目前最标准的也是VS开发工具默认做法,就是将运行时库通过导入表静态链接到PE文件(EXE或DLL),同时将manifest嵌入到PE文件的资源里,资源号是RT_MANIFEST(24),再交给系统的PE加载器去自动加载对应的运行时库。

      虽然本文是说MSVCR90.DLL,但原理上是可以适用于各种各样的运行时库的。



#include <string>
#include <windows.h>
#if !defined(_UNICODE) && !defined(UNICODE)
#define tstring std::string
#else
#define tstring std::wstring
#endif
#define TSTRING tstring
void LoadMSVCRT90()
{
	TSTRING sDllName = _T("");
	HMODULE hLib = NULL;
	ACTCTX aActCtx = { 0 };
	HANDLE hCtx = NULL;
	ULONG_PTR lpCookie = 0L;
	memset(&aActCtx, 0, sizeof(aActCtx));
	aActCtx.cbSize = sizeof(aActCtx);
	aActCtx.lpSource = _T("MSVCRT.manifest");
	hCtx = ::CreateActCtx(&aActCtx);
	if (hCtx == INVALID_HANDLE_VALUE)
	{
		return;
	}
	::ActivateActCtx(hCtx, &lpCookie);
	sDllName = _T("MSVCR90.DLL");
	hLib = ::LoadLibrary(sDllName.c_str());
	if (!hLib || hLib == INVALID_HANDLE_VALUE)
	{
		return;
	}
	::DeactivateActCtx(0, lpCookie);
	::ReleaseActCtx(hCtx);
}
/*************************************************************************************************
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>
*************************************************************************************************/


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回