是的,您可以在同一项目中使用相同的代码库针对x86和x64进行目标设置。通常情况下,在VS.NET中创建正确的解决方案配置即可实现自动适配(尽管对于完全非托管的DLL的P/Invoke可能需要一些条件代码):我发现需要特别注意的项目包括:
- 引用外部托管程序集,名称相同但具有特定位数(这也适用于COM互操作程序集)
- MSI包(如已经注意到的那样,将需要针对x86或x64进行目标设置)
- 任何基于.NET Installer类的自定义操作
程序集引用问题无法完全在VS.NET中解决,因为它只允许您向项目添加给定名称的引用一次。要解决此问题,请手动编辑您的项目文件(在VS中,右键单击解决方案资源管理器中的项目文件,选择卸载项目,然后再次右键单击并选择编辑)。添加对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中重新加载项目后,程序集引用对话框会因这些更改而有些混乱,你可能会遇到一些关于目标处理器错误的警告,但是你的所有构建都将正常工作。
解决MSI问题是接下来要做的事情,不幸的是,这需要一个非VS.NET工具:我更喜欢使用Caphyon的
高级安装程序,因为它非常出色地完成了所涉及的基本技巧(创建一个共同的MSI,以及32位和64位特定的MSI,并使用.EXE安装程序提取正确的版本并在运行时执行所需的修复)。您可能可以使用其他工具或
Windows Installer XML (WiX) 工具集来实现相同的结果,但Advanced Installer使事情变得如此容易(而且价格也相当实惠),以至于我从未真正看过其他选择。
然而,在使用高级安装程序时,您仍然可能需要WiX来进行.NET安装程序类自定义操作。尽管使用VersionNT64和NOT VersionNT64执行条件指定某些仅在某些平台上运行的操作是微不足道的,但内置AI自定义操作将在64位机器上使用32位框架执行。
这可能会在未来的版本中得到修复,但是现在(或者使用具有相同问题的不同工具创建您的MSI时),您可以使用WiX 3.0的托管自定义操作支持来创建具有正确位数的操作DLL,这将使用相应的框架执行。
编辑:从版本8.1.2开始,高级安装程序正确支持64位自定义操作。不幸的是,自我的原始答案以来,它的价格已经大幅上涨,尽管与InstallShield及其同类产品相比,仍然具有极高的性价比...
编辑:如果您的DLL已在全局程序集缓存中注册,您也可以使用标准的引用标记来实现此目的(以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>
该条件也适用于所有构建类型,包括发布版和调试版,并仅指定处理器架构。