VC编写的程序不能在其他机器上运行的解决方案(续)

简介:

我在前面的文章里面提到由于side-by-side问题导致的VC编写的程序不能正常启动的问题的解决方案,这种方法是针对于单个可执行文件的解决方案,但是有的时候你可能会碰到另外一种情况也是由于side-by-side问题导致的,你的程序支持插件,当你的程序试图加载一个依赖于CRTDLL的时候,Windows告诉你不能加载DLL

 

比如微软在06年发布了CLR的开源版本,你在自己机器上用Visual Studio 2008编译以后,在使用Windbg + SOS调试托管代码的时候,Windbg可能会报告无法加载SOS的错误,例如下面的Windbg输出:

CommandLine: binaries.x86dbg.rotor"clix.exe pptclrt"ForAndForeach.exe

Executable search path is:

ModLoad: 7c800000 7c91e000   C:"WINDOWS"system32"kernel32.dll

ModLoad: 79e00000 79e0a000   C:"sscli20"binaries.x86dbg.rotor"sscoree.dll

(1484.1358): Break instruction exception - code 80000003 (first chance)

ntdll!DbgBreakPoint:

7c92120e cc              int     3

0:000> .load C:"sscli20"binaries.x86dbg.rotor"sos.dll

The call to LoadLibrary(C:"sscli20"binaries.x86dbg.rotor"sos.dll) failed, Win32 error 0n126

    "找不到指定的模块。"

Please check your debugger configuration and/or network access.

1.         当你在C:"sscli20"binaries.x86dbg.rotor"查看sos.dll是否存在的时候,将会惊讶地发现sos.dll静静地躺在文件夹里面等待别人发现它!然而为什么Windbg在调用操作系统LoadLibrary API的时候,操作系统会报告说“找不到指定的模块”呢?

2.         再仔细看一下,文件夹里面有sos.dll.manifest文件,确认一下内容,里面依赖的CRT版本的的确确是我们机器上安装好了的CRT版本呀!

<?xml version='1.0encoding='UTF-8standalone='yes'?>

<assembly xmlns='urn:schemas-microsoft-com:asm.v1manifestVersion='1.0'>

 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">

    <security>

      <requestedPrivileges>

        <requestedExecutionLevel level='asInvokeruiAccess='false' />

      </requestedPrivileges>

    </security>

 </trustInfo>

 <dependency>

    <dependentAssembly>

      <assemblyIdentity type='win32name='Microsoft.VC90.DebugCRT'version='9.0.21022.8processorArchitecture='x86'publicKeyToken='1fc8b3b9a1e18e3b' />

    </dependentAssembly>

 </dependency>

</assembly>

 

3.         于是我们猜测,可能是操作系统在加载dll的时候,并不查看dllmanifest文件,也就不会去加载CRT,从而导致SOS.DLL加载失败。

4.         那既然是怀疑操作系统不会根据dllmanifest文件来加载CRT的话,那我们是不是可以为Windbg.exe创建一个manifest文件来告诉操作系统在运行windbg的时候先把CRT加载进内存,然后在SOS加载的时候,因为CRT已经提前加载进Windbg的进程中了,也就不会有依赖项不能加载而导致SOS加载失败的问题了。

5.         接着将sos.dll.manifest复制一份并且重命名为windbg.exe.manifest,最后把它放到windbg.exe同一个文件夹里面去。再启动windbg加载sos试一下,还是不行,郁闷!

 

难道就像以前昭君出塞的故事一样,是因为SOS.DLL没有潜规则导致操作系统不愿意加载它?

据《西京杂记》的描述,元帝后宫的美女实在太多了,根本不可能一个个当面鉴赏。他便让“黄门画者”(宫廷画工)把她们的肖像全都画出来,交给自己挑选。

 

  宫女们的命运鬼使神差地掌握在了画工们的手中,她们便争相向这些画工行贿,多则10万钱,再少也不低于5万钱。负责给王昭君画像的画工叫毛延寿,王昭君自恃才貌双绝,不愿屈身相求,更拿不出这么多钱来贿赂他。毛延寿便在她的脸上随手点了一颗黑痣。

 

  元帝对这么一个并不完美的女子,自然提不起兴趣。因此,王昭君入宫好几年,都没有机会被召幸,内心的委屈与悲怨不言而喻。

 

正如哥们我仍然单身,一定不能放过一个美女一样!我们也不能让这种问题就此埋没下去,于是我们再次想起mt.exe程序,实际上我们应该叫它(mp.exe – 媒婆.exe),:)

让我们看看Windbg资源里面是否已经嵌入一个manifest文件了,才导致我们自己加的manifest没有作用,使用下面的命令看一看:

mt -inputresource:d:"Debuggers"windbg.exe;#1 -output:test.manifest

哼哼,果然有一个:

<?xml version="1.0encoding="UTF-8standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1manifestVersion="1.0">

<assemblyIdentity name="Microsoft.Windows.SdkTools.windbgprocessorArchitecture="x86"version="6.9.0.0type="win32"></assemblyIdentity>

<description>Windows GUI symbolic debugger</description>

<dependency>

    <dependentAssembly>

        <assemblyIdentity type="win32name="Microsoft.Windows.Common-Controls"version="6.0.0.0processorArchitecture="*publicKeyToken="6595b64144ccf1dflanguage="*"></assemblyIdentity>

    </dependentAssembly>

</dependency>

</assembly>

但是里面并没有说windbg不依赖CRT,因此操作系统就随便加载了一个CRT敷衍了事了,既然知道问题所在了,那么我们要做的事情就比较简单了,将Windbg资源里面的manifest文件更新一下,然后再将Debug CRT包拷贝到Windbg同一个目录里面就可以了。

 

1.         test.manifest文件更新成:

<?xml version="1.0encoding="UTF-8standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1manifestVersion="1.0">

<assemblyIdentity name="Microsoft.Windows.SdkTools.windbg"processorArchitecture="x86version="6.9.0.0type="win32"></assemblyIdentity>

<description>Windows GUI symbolic debugger</description>

<dependency>

    <dependentAssembly>

        <assemblyIdentity type="win32name="Microsoft.Windows.Common-Controls"version="6.0.0.0processorArchitecture="*publicKeyToken="6595b64144ccf1df"language="*"></assemblyIdentity>

    </dependentAssembly>

</dependency>

 

 <dependency>

    <dependentAssembly>

      <assemblyIdentity type='win32name='Microsoft.VC90.DebugCRT'version='9.0.21022.8processorArchitecture='x86'publicKeyToken='1fc8b3b9a1e18e3b' />

    </dependentAssembly>

 </dependency>

</assembly>

 

2.         执行命令将Windbg资源里面的manifest文件更新一下。

mt -updateresource:d:"Debuggers"windbg.exe;#1 -manifest test.manifest

标签:  VCC++

本文转自 donjuan 博客园博客,原文链接:  http://www.cnblogs.com/killmyday/archive/2009/02/20/1394597.html  ,如需转载请自行联系原作者

相关文章
|
25天前
|
小程序 数据可视化 前端开发
编写小程序用什么软件
编写小程序用什么软件
40 5
|
4月前
|
运维 监控 Java
函数计算产品使用问题之Java 17作为运行时环境,并已使用WebIDE完成代码的修改和调试,如何部署代码
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
6月前
LabVIEW配置可执行程序以运行更高版本的运行引擎
LabVIEW配置可执行程序以运行更高版本的运行引擎
98 1
|
6月前
|
自然语言处理 Java 编译器
程序是如何运行的(一)
程序是如何运行的(一)
|
存储 自然语言处理 Linux
程序的环境
程序的环境
85 0
程序的环境
|
程序员 C语言
Win知识 - 程序是怎样跑起来的——了解程序运行方式的必要性
Win知识 - 程序是怎样跑起来的——了解程序运行方式的必要性
143 0
Win知识 - 程序是怎样跑起来的——了解程序运行方式的必要性
|
存储 API C语言
Win知识 - 程序是怎样跑起来的——应用和硬件无关?
Win知识 - 程序是怎样跑起来的——应用和硬件无关?
143 0
Win知识 - 程序是怎样跑起来的——应用和硬件无关?
|
存储 C语言
Win知识 - 程序是怎样跑起来的——函数内部的处理
Win知识 - 程序是怎样跑起来的——函数内部的处理
86 0
Win知识 - 程序是怎样跑起来的——函数内部的处理
|
编解码 IDE 测试技术
如何测试Windows应用程序
如何测试Windows应用程序
377 0
|
XML JavaScript 前端开发
在FreeSWITCH中执行长期运行的嵌入式脚本–Lua语言例子
众所周知,FreeSWITCH中可以使用嵌入式的脚本语言javascript、lua等来控制呼叫流程。而更复杂一点操作可能就需要使用Event Socket了。其实不然,嵌入式的脚本也可以一直运行,并可以监听所有的Event,就像使用Event Socket起一个单独的Daemon一样。