2009-11-08 72 views
0

我們有一個32位混合C/C++應用程序,我們正試圖部署到世界上。它自然使用C和C++運行時DLL。我們使用VS 2005用於32位混合C/C++應用程序的Microsoft程序集配置

通過VS2005構建的清單如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.42" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

我們的船這是在同一目錄下的「應用程序」文件,命名爲 (爲保護無辜)「application.exe.manifest」。

從表面上看,這是合理的。但是,在安裝某些 系統,我們得到當「application.exe」啓動消息:

此應用程序未能啓動,因爲應用程序配置是不正確的治療,這是

的一種方式從MSDN運行VCRedist_x86.exe。 (不幸的是, 而我們可以運行它,我們不知道它到底是什麼做的。 這似乎是在的SxS目錄停車的DLL。還有什麼 它能做什麼?)

一)MS文檔似乎表明,大會必須直接有assemblyIdentity 標籤裝配標籤下,名稱應用程序本身。 這在這裏顯然不存在,但是如果我們刪除它,那麼清單似乎在部分工作,即使DLL存在,應用程序也不會啓動。

b)中值得注意的是該組件沒有提及C運行時DLL。我需要手動添加嗎?

c)我們不希望依賴於正確的版本DLL是否存在在目標機器上。假設程序集清楚地說明要使用哪個DLL,那麼我們如何確保我們需要的DLL在目標系統上? (特別是,我們不想運行VCRedist或要求我們的客戶這樣做)。在程序集出現之前,我們通過簡單地將C和C++ DLL放在與應用程序.exe文件相同的目錄中來解決此問題,並且Windows會首先在那裏查找它們。我們仍然可以將C和C++ DLL放在同一個目錄中嗎?我無法從MS文檔中找到我可以找到SxS如何找到合適的相關程序集。

任何幫助表示讚賞。

回答

0

您可以靜態鏈接C/C++運行時。

您可以在代碼生成部分的C/C++編譯器選項中更改庫鏈接。改變從多線程[調試] DLL多線程[調試]的條目。

你的DLL然後將包含運行時所需要的部分,不需要單獨安裝。

+0

感謝您的建議。這是一個選項。但我想了解清單的工作原理。 – 2009-11-08 23:37:04

0

我永遠無法理解的東西表現如何都一起掛...但不是把C運行時的DLL在同一目錄下你的EXE嘗試複製整個「Microsoft.VC90。我的機器上的Visual Studio安裝(C:\ Program Files(x86)\ Microsoft Visual Studio 9.0 \ VC \ redist \ x86 \ Microsoft.VC90.CRT)中的redist文件夾中的「CRT」文件夾。

我相信Microsoft鼓勵使用共享庫並運行官方redist,因爲它正確安裝了庫,意味着它們可以修補可能在其中找到的安全問題。

+0

...嘗試複製整個...文件夾...到哪裏? *誰應該做這個複製(我認爲我們在這裏討論安裝程序,因爲這就是我們提供應用程序的方式)。我感到困惑...我已經安裝了很多下載,並且我從未被要求通過下載的工具運行VCRedist。顯示,圖書館如何在實踐中分享? – 2009-11-09 01:27:22

+0

將文件夾複製到與您的exe相同的目錄。 通常安裝程序會自行運行VCRedist作品(我相信它也可以作爲msi模塊使用)。 – 2009-11-09 01:41:29

+0

這確實是一件正確的事情。 Fusion(SxS加載程序)將在與可執行文件相同的目錄中探測「assemblyIdentity/@ name」.manifest(例如:Microsoft.VC80.CRT.manifest),以解析未存儲在SxS程序集緩存中的程序集。 如果您的客戶已經安裝了CRT重新安裝程序,它將使用SxS文件夾中的副本,從而爲您提供安全更新,並且如果其他正在運行的應用程序已在使用SxS CRT,則可以改進應用程序啓動和內存使用。 – 2009-11-09 06:07:29

1

a)清單xml驗證顯然有一些問題。根據Windows的版本,這可能會也可能不是問題。由於如此多的應用程序沒有正確地遵循模式(並且因爲它從未正確執行),所以我懷疑它在這裏將永遠是嚴格的。

b)C運行庫DLL在Microsoft.VC80.CRT.manifest文件中被引用,並將其引入到加載器依賴關係圖中。如果您對清單具有依賴性,則還會隱式地對DLL有依賴關係。

c)根據我以前的評論,除了安裝最新的redist系統外,正確的事情是將CRT清單和所有三個DLL放在應用程序目錄中。這在SxS: Private AssembliesInstalling Side-by-side Assemblies as Private Assemblies下記錄得很差。探針順序在Assembly Searching Sequence中定義。

通常,SxS綁定失敗會在描述錯誤的應用程序(用於Vista +)或系統事件日誌(Vista之前)中輸入一個條目。

 
Activation context generation failed for "C:\TEMP\sxs\PEVerify.exe".Error in manifest or policy file "C:\TEMP\sxs\Microsoft.VC90.CRT.MANIFEST" on line 4. 
Component identity found in manifest does not match the identity of the component requested. 
Reference is Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a18e3b",type="win32",version="9.0.21022.8". 
Definition is Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.30729.1". 
Please use sxstrace.exe for detailed diagnosis. 

您可以使用sxstrace.exe中(Vista的+),看看有什麼裝載機實際上做。 Junfeng在Diagnosing SideBySide failures中詳細介紹了這一點。

爲了更好地理解運行時發生了什麼(清單已被解析並且依賴關係存在之後),爲圖像文件啓用「顯示Loader捕捉」(只是文件名和擴展名,不要輸入目錄名,如下所示:「notepad.exe」)使用gflags.exe。在windbg下運行你的應用程序(Visual Studio的調試器也可以工作)並查看輸出。確保在完成調試時禁用加載器捕捉,因爲即使沒有附加調試器,它也會減慢應用程序的速度。示例輸出如下所示:

 
2d6c:36b4 @ 1246428223 - LdrpHandleOneOldFormatImportDescriptor - INFO: DLL "C:\Program Files\Microsoft SDKs\Windows\v6.1\Bin\PEVerify.exe" imports "MSVCR90.dll" 
2d6c:36b4 @ 1246428223 - LdrpMapDll - INFO: Mapping static redirected DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" 
ModLoad: 4fbd0000 4fc73000 C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll 
2d6c:36b4 @ 1246428285 - LdrpMapDll - INFO: Mapped DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" at address 4FBD0000 
2d6c:36b4 @ 1246428285 - LdrpHandleOneOldFormatImportDescriptor - INFO: DLL "C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll" imports "KERNEL32.dll"