VC编写的程序不能在其他机器上运行的解决方案(续)
我在前面的文章里面提到由于side-by-side問(wèn)題導(dǎo)致的VC編寫(xiě)的程序不能正常啟動(dòng)的問(wèn)題的解決方案,這種方法是針對(duì)于單個(gè)可執(zhí)行文件的解決方案,但是有的時(shí)候你可能會(huì)碰到另外一種情況—也是由于side-by-side問(wèn)題導(dǎo)致的,你的程序支持插件,當(dāng)你的程序試圖加載一個(gè)依賴于CRT的DLL的時(shí)候,Windows告訴你不能加載DLL。
?
比如微軟在06年發(fā)布了CLR的開(kāi)源版本,你在自己機(jī)器上用Visual Studio 2008編譯以后,在使用Windbg + SOS調(diào)試托管代碼的時(shí)候,Windbg可能會(huì)報(bào)告無(wú)法加載SOS的錯(cuò)誤,例如下面的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.?????????當(dāng)你在C:"sscli20"binaries.x86dbg.rotor"查看sos.dll是否存在的時(shí)候,將會(huì)驚訝地發(fā)現(xiàn)sos.dll靜靜地躺在文件夾里面等待別人發(fā)現(xiàn)它!然而為什么Windbg在調(diào)用操作系統(tǒng)LoadLibrary API的時(shí)候,操作系統(tǒng)會(huì)報(bào)告說(shuō)“找不到指定的模塊”呢?
2.?????????再仔細(xì)看一下,文件夾里面有sos.dll.manifest文件,確認(rèn)一下內(nèi)容,里面依賴的CRT版本的的確確是我們機(jī)器上安裝好了的CRT版本呀!
| <?xml?version='1.0'?encoding='UTF-8'?standalone='yes'?> <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'?/> ????? </requestedPrivileges> ??? </security> ?</trustInfo> ?<dependency> ??? <dependentAssembly> ????? <assemblyIdentity?type='win32'?name='Microsoft.VC90.DebugCRT'version='9.0.21022.8'?processorArchitecture='x86'publicKeyToken='1fc8b3b9a1e18e3b'?/> ??? </dependentAssembly> ?</dependency> </assembly> |
?
3.?????????于是我們猜測(cè),可能是操作系統(tǒng)在加載dll的時(shí)候,并不查看dll的manifest文件,也就不會(huì)去加載CRT,從而導(dǎo)致SOS.DLL加載失敗。
4.?????????那既然是懷疑操作系統(tǒng)不會(huì)根據(jù)dll的manifest文件來(lái)加載CRT的話,那我們是不是可以為Windbg.exe創(chuàng)建一個(gè)manifest文件來(lái)告訴操作系統(tǒng)在運(yùn)行windbg的時(shí)候先把CRT加載進(jìn)內(nèi)存,然后在SOS加載的時(shí)候,因?yàn)镃RT已經(jīng)提前加載進(jìn)Windbg的進(jìn)程中了,也就不會(huì)有依賴項(xiàng)不能加載而導(dǎo)致SOS加載失敗的問(wèn)題了。
5.?????????接著將sos.dll.manifest復(fù)制一份并且重命名為windbg.exe.manifest,最后把它放到windbg.exe同一個(gè)文件夾里面去。再啟動(dòng)windbg加載sos試一下,還是不行,郁悶!
?
難道就像以前昭君出塞的故事一樣,是因?yàn)镾OS.DLL沒(méi)有潛規(guī)則導(dǎo)致操作系統(tǒng)不愿意加載它?
| 據(jù)《西京雜記》的描述,元帝后宮的美女實(shí)在太多了,根本不可能一個(gè)個(gè)當(dāng)面鑒賞。他便讓“黃門(mén)畫(huà)者”(宮廷畫(huà)工)把她們的肖像全都畫(huà)出來(lái),交給自己挑選。 ? 宮女們的命運(yùn)鬼使神差地掌握在了畫(huà)工們的手中,她們便爭(zhēng)相向這些畫(huà)工行賄,多則10萬(wàn)錢(qián),再少也不低于5萬(wàn)錢(qián)。負(fù)責(zé)給王昭君畫(huà)像的畫(huà)工叫毛延壽,王昭君自恃才貌雙絕,不愿屈身相求,更拿不出這么多錢(qián)來(lái)賄賂他。毛延壽便在她的臉上隨手點(diǎn)了一顆黑痣。 ? 元帝對(duì)這么一個(gè)并不完美的女子,自然提不起興趣。因此,王昭君入宮好幾年,都沒(méi)有機(jī)會(huì)被召幸,內(nèi)心的委屈與悲怨不言而喻。 |
?
正如哥們我仍然單身,一定不能放過(guò)一個(gè)美女一樣!我們也不能讓這種問(wèn)題就此埋沒(méi)下去,于是我們?cè)俅蜗肫餸t.exe程序,實(shí)際上我們應(yīng)該叫它(mp.exe –?媒婆.exe),:)
讓我們看看Windbg資源里面是否已經(jīng)嵌入一個(gè)manifest文件了,才導(dǎo)致我們自己加的manifest沒(méi)有作用,使用下面的命令看一看:
mt -inputresource:d:"Debuggers"windbg.exe;#1 -output:test.manifest
哼哼,果然有一個(gè):
| <?xml?version="1.0"?encoding="UTF-8"?standalone="yes"?> <assembly?xmlns="urn:schemas-microsoft-com:asm.v1"?manifestVersion="1.0"> <assemblyIdentity?name="Microsoft.Windows.SdkTools.windbg"?processorArchitecture="x86"version="6.9.0.0"?type="win32"></assemblyIdentity> <description>Windows GUI symbolic debugger</description> <dependency> ??? <dependentAssembly> ??????? <assemblyIdentity?type="win32"?name="Microsoft.Windows.Common-Controls"version="6.0.0.0"?processorArchitecture="*"?publicKeyToken="6595b64144ccf1df"?language="*"></assemblyIdentity> ??? </dependentAssembly> </dependency> </assembly> |
但是里面并沒(méi)有說(shuō)windbg不依賴CRT,因此操作系統(tǒng)就隨便加載了一個(gè)CRT敷衍了事了,既然知道問(wèn)題所在了,那么我們要做的事情就比較簡(jiǎn)單了,將Windbg資源里面的manifest文件更新一下,然后再將Debug CRT包拷貝到Windbg同一個(gè)目錄里面就可以了。
?
1.?????????將test.manifest文件更新成:
| <?xml?version="1.0"?encoding="UTF-8"?standalone="yes"?> <assembly?xmlns="urn:schemas-microsoft-com:asm.v1"?manifestVersion="1.0"> <assemblyIdentity?name="Microsoft.Windows.SdkTools.windbg"processorArchitecture="x86"?version="6.9.0.0"?type="win32"></assemblyIdentity> <description>Windows GUI symbolic debugger</description> <dependency> ??? <dependentAssembly> ??????? <assemblyIdentity?type="win32"?name="Microsoft.Windows.Common-Controls"version="6.0.0.0"?processorArchitecture="*"?publicKeyToken="6595b64144ccf1df"language="*"></assemblyIdentity> ??? </dependentAssembly> </dependency> ? ?<dependency> ??? <dependentAssembly> ????? <assemblyIdentity?type='win32'?name='Microsoft.VC90.DebugCRT'version='9.0.21022.8'?processorArchitecture='x86'publicKeyToken='1fc8b3b9a1e18e3b'?/> ??? </dependentAssembly> ?</dependency> </assembly> |
?
2.?????????執(zhí)行命令將Windbg資源里面的manifest文件更新一下。
mt -updateresource:d:"Debuggers"windbg.exe;#1 -manifest test.manifest
總結(jié)
以上是生活随笔為你收集整理的VC编写的程序不能在其他机器上运行的解决方案(续)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php pdf 文字水印图片,php如何
- 下一篇: VS 中配置使用Visual SVN系列