2009-07-06 42 views
4

我們有一個非常大的項目,主要是用C#編寫的,它有一些用C++編寫的小而重要的組件。我們將.NET 2.0的RTM作爲最低要求版本。到目前爲止,爲了滿足這個要求,我們已經確保在我們的構建盒上只有.NET 2.0的RTM,這樣C++片斷就可以鏈接到該版本。如何定位特定版本的C++運行時?

更新:引起該問題的 C++組件是混合模式C++組件被裝載到被管理的過程。

不幸的是,當confiker被設置爲在4月1日做某件事情時,我們的企業IT大力推動修補所有內容並使其保持最新狀態,因此,通過3.5 SP1的所有內容都安裝到了構建箱中。我們嘗試卸載之前發生的所有事情,但現在我們無法滿足我們的最低要求,因爲構建在該特定框上的任何內容都需要.NET 2.0 SP1。

由於該框似乎是因爲我們不能卸載違規版本,是否有任何方法來構建程序集並明確告訴他們使用.NET 2.0的RTM(這是v2.0.50727。 42)?我已經看到了使用清單的頁面,但我無法弄清楚如何實際實現一個適當的清單,並將其納入程序集。我的專業知識是在託管世界,所以我在這方面有點虧損。

任何人都可以解釋我可以如何使這些程序集的目標.NET 2.0 RTM SxS程序集?

謝謝!

回答

8

雖然我敢肯定,克里的回答和代碼示例(謝謝,克里斯托弗!)是一個更優雅的解決方案的一部分,我們的槍下得到這個出了門,發現一個很相似,但不同,解決方案。

的第一步是創建一個清單程序集:

<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type='win32' name='Microsoft.VC80.DebugCRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> 
    </dependentAssembly> 
    </dependency> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

接下來,您必須設置「生成清單」選項設置爲「否」下的配置屬性 - >鏈接器 - >清單文件,並在「嵌入清單」選項設置爲「否」下的配置屬性 - >清單工具 - >輸入和輸出。

最後,讓您的新清單到組件添加下面的命令到項目的生成後步驟:

mt.exe /manifest "$(ProjectDir)cppassembly.dll.manifest" /outputresource:"$(TargetDir)\cppassembly.dll";#2 -out:"$(TargetDir)\cppassembly.dll.manifest" 

一旦建成,我們可以打開Visual Studio中的DLL來查看RT_MANIFEST下的表現和確認它有我們的清單!

當我把克里斯托弗的代碼放入stdafx.h中時,它最終將其添加爲附加的依賴項...清單仍在尋找v8.0.50727.762。它生成的清單看起來像這樣:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> 
    </dependentAssembly> 
    </dependency> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> 
    </dependentAssembly> 
    </dependency> 
    <dependency> 
    <dependentAssembly> 
     <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> 
    </dependentAssembly> 
    </dependency> 
</assembly> 

我無法追查到另一個開關,將刪除或清除現有的依賴關係。我喜歡克里斯托弗的方法比後建立步驟更好,但現在這個工作。如果任何人有任何額外的關於如何清除任何現有的依賴關係,將是偉大的輸入。

謝謝!

3

是的。在您的項目屬性中,有一個頁面指示運行時間。有一個下拉列表列出了所有可用的運行時間。選擇一個適合你的。 (對於VS 2008:右鍵單擊項目 - >屬性,編譯選項卡,高級編譯器設置按鈕 - >目標框架)

我們現在就做這個。我們想轉到VS 2008,但我們正在逐步完成。所以現在我們有一個VS 2008的解決方案,但所有的項目仍然瞄準.Net 2.0。因此,當我們編譯和部署時,我們不需要在我們的測試盒上安裝.Net 3.5的東西。

UPDATE:

要強制本地程序鏈接到的.dll的特定版本,你可能想使用這樣的事:

#pragma message ("Explicit link to generate a manifest entry for MFC.") 

#if defined (_DEBUG) 

#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.VC80.DebugMFC' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'\"") 

#else 

#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.VC80.MFC' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'\"") 

#endif 

除,即代替MFC,你應該爲.Net .DLL找到正確的值。

有理由相信你不能在同一個盒子上安裝.Net 2.0 SP1和.Net 2.0。所以讓它在這個盒子上工作可能會非常痛苦。它可能是更好地旋轉了一個新的構建虛擬機,你可以在安裝的時候,未打補丁的Net框架(如果你甚至可以得到它保持了。)

否則,你將需要複製所有的建設 - 將時間文件放到當前框中,然後根據您的構建類型對包含和庫路徑進行調整。可能這比它的價值更令人頭疼。

+1

我相信只適用於.Net項目。我不認爲這適用於非託管C++項目。我一直在編譯C++代碼時發現Visual Studio定位最新版本的運行時。 – 2009-07-06 15:37:41

+0

正確...只適用於託管項目。我希望這是非常容易的非託管。 :) – 2009-07-06 15:53:24

+0

對不起,我以爲你想要託管C++。您可以通過選擇您定位的SDK來爲本機C++執行類似的操作。這基本上涉及設置正確的編譯器路徑。對於VS2005,有一個名爲vcvars.bat的批處理文件 您是使用makefile生成還是使用devenv? – Christopher 2009-07-06 16:25:58

0

想知道你想要的CorBindToRuntime。這將允許您指定C++加載的CLR版本。

1

我知道這是一個黑客,但我已經使出產生明顯的外部,並用記事本修改它。在一個捏,它爲我做了伎倆。就我而言,我期待有一個VC++ 2005應用程序指向.762 CRT。

祝你好運! 特里

1

約翰的回答爲我們工作。在Visual C++ 2005,編譯器生成清單同時包含762個4053版本MFC和CRT的。我們從清單中刪除了4053版本,並轉到上述手動步驟。 (內部代碼實際上會搶4053,因爲它是一個公認的安全修復超過762,但規範是必要的或鏈接將失敗。)

Ted的博客(tedwvc.wordpress.com)發佈給了我們提示,但他的解決方案沒有爲我們工作。這種方法在這裏工作。

2

約翰真的把我放在正確的軌道上解決同樣的問題。我想提出一個老VS2005 C++(非CLR)項目略有變化。我的開發機器有所有的更新,所以VS2005創建了對最新版本的MFC80和MSVCx80 DLL的引用,並且可執行文件無法在目標機器上運行,因爲這些版本不可用,我也沒有選擇更新這些機器。所以我需要控制嵌入在可執行文件中的清單中的assmelby依賴關係。這似乎與John正在研究的問題大致相同。從他的附加信息開始,這對我來說很有用。

在PROJECTDIR創建program.exe.debug.manifestprogram.exe.release.manifest文件用適當的組件的參考信息。不要將這些添加到項目或鏈接器中,嘗試在每個構建中都包含它們。然後設置項目屬性如下:

連接器 - >清單文件選項

  • 生成清單:沒有
  • 清單文件:空白
  • 附加清單依賴關係:空白
  • 允許隔離:是

清單工具 - >輸入和輸出選項

  • 附加清單文件:$(PROJECTDIR)$(TargetFileName)$(ConfigurationName).manifest的
  • 輸入資源艙單:空白
  • 嵌入清單:是
  • 輸出清單文件:(自動填入)
  • 清單資源文件:(自動填充)
  • 生成目錄文件:沒有
  • 相關信息文件:$(IntDir)\ mt.dep(自動填充)

從我的測試看來,它不會生成任何其他清單文件,並將您的手動編碼的清單信息作爲RT_MANIFTEST資源#1嵌入到EXE中。

清單中的工具選項,「輸出清單文件」和「清單資源文件」被自動填入,即使我清除它們。

這似乎允許我控制程序集依賴關係並獲得可執行文件在目標機器上運行。額外的好處是我不必使用用於其他目的的構建後步驟。通過操作鏈接器和清單工具選項,可以獲得相同的結果。

對不起,我無法更新屏幕截圖,但我是一個新用戶,圖像是不允許的。

相關問題