Dot-Net

在同一解決方案/項目中使用 Visual Studio 以 32 位和 64 位為目標

  • September 28, 2008

我對如何設置我的視覺工作室建構以實現多目標有點進退兩難。

背景:c# .NET v2.0 帶有 p/invoking 到第 3 方 32 位 DLL,SQL compact v3.5 SP1,帶有安裝項目。現在,平台目標設置為 x86,因此可以在 Windows x64 上執行。

第 3 方公司剛剛發布了他們的 DLL 的 64 位版本,我想建構一個專用的 64 位程序。

這提出了一些我還沒有得到答案的問題。我想擁有完全相同的程式碼庫。我必須使用對 32 位 DLL 集或 64 位 DLL 的引用來建構。(第 3 方和 SQL Server Compact)

這可以通過 2 組新配置(Debug64 和 Release64)來解決嗎?

我必須創建 2 個單獨的設置項目(std.visual studio 項目,沒有 Wix 或任何其他實用程序),還是可以在同一個 .msi 中解決?

歡迎任何想法和/或建議。

是的,您可以在同一個項目中使用相同的程式碼庫同時定位 x86 和 x64。一般來說,如果您在 VS.NET 中創建正確的解決方案配置,一切都會正常工作(儘管對完全非託管的 DLL 的 P/Invoke 很可能需要一些條件程式碼):我發現需要特別注意的項目是:

  • 對具有相同名稱但具有自己特定位數的外部託管程序集的引用(這也適用於 COM 互操作程序集)
  • MSI 包(如前所述,它需要以 x86 或 x64 為目標)
  • MSI 包中任何基於 .NET 安裝程序類的自定義操作

程序集引用問題無法在 VS.NET 中完全解決,因為它只允許您將具有給定名稱的引用添加到項目中一次。要解決此問題,請手動編輯您的項目文件(在 VS 中,右鍵點擊解決方案資源管理器中的項目文件,選擇解除安裝項目,然後再次右鍵點擊並選擇編輯)。添加對例如 x86 版本程序集的引用後,您的項目文件將包含以下內容:

<Reference Include="Filename, ..., processorArchitecture=x86">
 <HintPath>C:\path\to\x86\DLL</HintPath>
</Reference>

將該 Reference 標記包裝在 ItemGroup 標記中,指示它適用的解決方案配置,例如:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
  <Reference ...>....</Reference>
</ItemGroup>

然後,複製並粘貼整個 ItemGroup 標記,並對其進行編輯以包含 64 位 DLL 的詳細資訊,例如:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
 <Reference Include="Filename, ..., processorArchitecture=AMD64">
    <HintPath>C:\path\to\x64\DLL</HintPath>
  </Reference>
</ItemGroup>

在 VS.NET 中重新載入您的項目後,Assembly Reference 對話框會因這些更改而有點混亂,並且您可能會遇到一些關於帶有錯誤目標處理器的程序集的警告,但您的所有建構都可以正常工作。

接下來是解決 MSI 問題,不幸的是,這需要一個非 VS.NET 工具:為此,我更喜歡 Caphyon 的Advanced Installer,因為它完成了所涉及的基本技巧(創建一個通用 MSI,以及 32 位和 64 位特定的 MSI,並使用 .EXE 安裝程序啟動器來提取正確的版本並在執行時進行所需的修復)非常非常好。

您可能可以使用其他工具或Windows Installer XML (WiX) 工具集獲得相同的結果,但是 Advanced Installer 使事情變得如此簡單(而且價格相當實惠),以至於我從未真正看過替代品。

即使使用高級安裝程序,您可能仍然需要 WiX 的一件事是用於您的 .NET 安裝程序類自定義操作。儘管指定僅應在某些平台上執行的某些操作(分別使用 VersionNT64 和 NOT VersionNT64 執行條件)是微不足道的,但內置的 AI 自定義操作將使用 32 位框架執行,即使在 64 位機器上也是如此.

這可能會在未來的版本中得到修復,但是現在(或者在使用不同的工具來創建具有相同問題的 MSI 時),您可以使用 WiX 3.0 的託管自定義操作支持來創建具有適當位數的操作 DLL將使用相應的框架執行。


編輯:從 8.1.2 版開始,高級安裝程序正確支持 64 位自定義操作。不幸的是,自從我最初的回答以來,它的價格已經上漲了很多,儘管與 InstallShield 及其同類產品相比,它仍然非常物有所值……


編輯:如果您的 DLL 在 GAC 中註冊,您也可以通過這種方式使用標準引用標記(以 SQLite 為例):

<ItemGroup Condition="'$(Platform)' == 'x86'">
   <Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x64'">
   <Reference Include="System.Data.SQLite, Version=1.0.80.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64" />
</ItemGroup>

條件也減少到所有建構類型、發布或調試,並且只指定處理器架構。

引用自:https://stackoverflow.com/questions/145803