2008-09-28 62 views
103

我有一个困境,关于如何设置我的Visual Studio构建多目标。针对32位和64位与Visual Studio在同一解决方案/项目

背景:c#.NET v2.0与p /调用到第三方32位DLL,SQL compact v3.5 SP1,带有安装项目。 现在,平台目标被设置为x86,因此它可以在Windows x64上运行。

第三方公司刚刚发布了它们的DLL的64位版本,我想构建一个专用的64位程序。

这提出了一些问题,我还没有得到答案。 我想要有完全相同的代码库。 我必须建立对32位DLL或64位DLL的引用。 (第三方和SQL Server Compact)

这可以通过2套新配置(Debug64和Release64)解决吗?我是否必须创建2个独立的安装项目(标准视觉工作室项目,没有Wix或任何其他实用工具),或者这可以在相同的.msi内解决吗?

任何想法和/或建议将受到欢迎。

+0

@Magnus·约翰逊:你可以用两种配置来完成一半的目标。 MSI有点困难。 – user7116 2008-09-28 13:33:26

回答

80

是的,你可以针对x86和x64的,在同一个项目相同的代码库。我发现需要特别注意的项目是:

一般来说,如果您创建VS.NET的解决方案的配置(虽然P/Invoke来完全托管DLL将最有可能需要一些有条件的代码)的东西会只是工作
  • 引用具有相同的名称,但其自身特定位数外管理组件(这也适用于COM互操作程序集)
  • MSI软件包(正如已经指出的,将需要针对x86或x64)
  • MSI包中的任何基于.NET Installer类的自定义操作

程序集引用问题无法在VS.NET中完全解决,因为它只允许您将具有给定名称的引用添加到项目中。要解决此问题,请手动编辑项目文件(在VS中,右键单击解决方案资源管理器中的项目文件,选择Unload Project,然后再次右键单击并选择编辑)。添加一个参考,比如说,组件的x86版本后,你的项目文件将包含类似:

<Reference Include="Filename, ..., processorArchitecture=x86"> 
    <HintPath>C:\path\to\x86\DLL</HintPath> 
</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问题是旁边,不幸的是这需要non-VS.NET工具:我喜欢Caphyon的Advanced Installer用于这一目的,因为它拉了所涉及的基本技巧(创建一个共同的微星,如以及32位和64位特定的MSI,并使用.EXE安装启动器来提取正确的版本,并在运行时进行必要的修正)非常非常好。

您可以使用其他工具或Windows Installer XML (WiX) toolset可能达到同样的效果,但先进的安装程序使事情那么容易(而且是相当实惠的那个),我从来没有真正看的替代品。你可能仍然需要维克斯因为虽然,采用先进的安装程序,即使

一件事,就是你的.NET安装类自定义操作。尽管指定仅应在特定平台上运行的某些操作(分别使用VersionNT64和Not VersionNT64执行条件)很简单,但即使在64位机器上,内置的AI自定义操作也将使用32位框架执行。

这可能会在将来的版本中修复,但现在(或使用不同的工具创建具有相同问题的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> 

该条件也降低到所有生成类型,释放或调试,只是指定的处理器体系结构。

+0

在Visual Studio 2008中,我发现 s不能嵌套。一旦我将新的设置在的其余部分之下,该解决方案就可以正常工作。我也必须将x86更改为AnyCPU,这可能与我的特定项目的历史有关。 – 2010-10-01 06:25:40

+0

高级安装程序看起来非常棒。 – Pat 2010-11-05 22:37:41

1

不确定你的问题的总体回答 - 但我想我会指出SQL Compact 3.5 SP1 download page的附加信息部分中的评论,看到你正在看x64 - 希望它有帮助。

由于SQL Server精简 SP1和 SQL Server压缩3.5和64位 SQL版本的32位版本更改的其他64位版本 支持,集中安装和混合 模式环境服务器紧凑3.5 SP1 可以创建似乎是 间歇性问题。为了尽量减少冲突的 潜力,并能够管理 客户端应用程序的 平台无关的部署,集中 安装使用 Windows安装程序(MSI)文件还 的SQL Server精简3.5 SP1的64位版本需要安装SQL Server Compact 3.5 SP1 MSI 文件的32位版本 。对于只有 需要64位版本的本机64位,私有 部署的应用程序,可以使用SQL Server Compact 3.5 SP1的 。

我看这是“包括32位SQLCE文件以及 64位档案”如果分配64位客户。

让我觉得生活很有意思..我必须说,我喜欢“似乎是间歇性问题”的线...听起来有点像“你在想象的东西,但以防万一,这样做......”

0

关于你最后一个问题。很可能你无法在单个MSI中解决这个问题。 如果您正在使用注册表/系统文件夹或任何相关的东西,MSI本身必须知道这一点,并且您必须准备一个64位MSI以在32位机器上正确安装。

有一种可能性,你可以让你的产品安装为一个32应用程序,仍然能够使其运行64位,但我认为这可能有点难以实现。

这是说我认为你应该能够保持一切代码基地。在我目前的工作场所,我们设法这样做了。 (但它确实花了一些杂耍,使一切发挥)

希望这可以帮助。 继承人链接到一些信息与32/64位的问题: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html

26

比方说,你有这些DLL打造两个平台,而且他们是在以下位置:

C:\whatever\x86\whatever.dll 
C:\whatever\x64\whatever.dll 

您只需从该编辑.csproj的文件:

<HintPath>C:\whatever\x86\whatever.dll</HintPath> 

要这样的:

<HintPath>C:\whatever\$(Platform)\whatever.dll</HintPath> 

然后,您应该能够建立您的项目针对这两个平台,以及MSB uild将查找所选平台的正确目录。

0

您可以采用不同产生两个解决方案和合并他们之后! 我为VS 2010做了这个,并且它工作正常。我不得不CMake的生成2个不同的解决方案,我合并他们

0

您可以使用一个的ItemGroup的条件在项目文件中的DLL引用。
无论何时更改活动配置,这将导致visual studio重新检查条件和引用。
只需为每个配置添加一个条件即可。

例子:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> 
    <Reference Include="DLLName"> 
     <HintPath>..\DLLName.dll</HintPath> 
    </Reference> 
    <ProjectReference Include="..\MyOtherProject.vcxproj"> 
     <Project>{AAAAAA-000000-BBBB-CCCC-TTTTTTTTTT}</Project> 
     <Name>MyOtherProject</Name> 
    </ProjectReference> 
    </ItemGroup> 
相关问题