是的,您可以在同一个项目中使用相同的代码库同时定位 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>
条件也减少到所有构建类型、发布或调试,并且只指定处理器架构。