在同一个解决方案/项目中将Visual Studio的32位和64位都用作目标

关于如何设置我的visual studio版本以实现多目标,我有点困惑。

背景:带有p / invoker到第三方32位DLL,SQL compact v3.5 SP1的c#.NET 2.0版本,带有一个安装项目。 目前,平台目标设置为x86,因此可以在Windows x64上运行。

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

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

这可以通过2套新配置(Debug64和Release64)解决吗?

我必须创建2个独立的安装项目(标准视觉工作室项目,没有维克斯或任何其他实用工具),或者这可以在同一个.msi内解决吗?

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


是的,您可以在同一个项目中使用相同的代码库来定位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:pathtox86DLL</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:pathtox64DLL</HintPath>
       </Reference>
    </ItemGroup>
    

    在VS.NET中重新加载项目之后,Assembly Reference对话框会被这些更改所困惑,并且您可能会遇到一些有关错误目标处理器的程序集的警告,但所有的构建都可以正常工作。

    解决MSI问题接下来就会出现,不幸的是,这需要一个非VS.NET工具:我更喜欢Caphyon的高级安装程序,因为它可以解决涉及的基本技巧(创建一个通用的MSI以及32位和64位特定的MSI,并且使用.EXE安装启动程序来提取正确的版本并在运行时执行所需的修复)非常非常好。

    使用其他工具或Windows安装程序XML(WiX)工具集可能可以达到相同的结果,但Advanced Installer使事情变得如此简单(并且相当实惠),我从未真正考虑过替代方案。

    即使使用高级安装程序,您仍然可能需要使用WiX的一件事是用于.NET Installer Class自定义操作。 尽管指定仅应在特定平台上运行的某些操作(分别使用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>
    

    该条件还可以简化为所有构建类型,发布或调试,并且只是指定处理器体系结构。


    假设您为这两个平台构建了DLL,并且它们位于以下位置:

    C:whateverx86whatever.dll
    C:whateverx64whatever.dll
    

    你只需要从这里编辑你的.csproj文件:

    <HintPath>C:whateverx86whatever.dll</HintPath>
    

    为此:

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

    然后,您应该能够针对这两个平台构建项目,并且MSBuild将查找所选平台的正确目录。


    不知道你的问题的总体答案 - 但我想我会在SQL Compact 3.5 SP1下载页面的其他信息部分指出一条评论,看看你在看x64 - 希望它有帮助。

    由于SQL Server Compact SP1和其他64位版本支持的更改,32位版本的SQL Server Compact 3.5和64位版本的SQL Server Compact 3.5 SP1的集中安装和混合模式环境可以创建看起来是间歇性的问题。 为了最大限度地减少冲突的可能性并启用托管客户端应用程序的平台中立部署,使用Windows Installer(MSI)文件集中安装64位版本的SQL Server Compact 3.5 SP1还需要安装32位版本的SQL Server Compact 3.5 SP1 MSI文件。 对于只需要本机64位的应用程序,可以使用64位版本的SQL Server Compact 3.5 SP1的专用部署。

    如果分发给64位客户端,我将其视为“包含32位SQLCE文件以及 64位文件”。

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

    链接地址: http://www.djcxy.com/p/75123.html

    上一篇: Targeting both 32bit and 64bit with Visual Studio in same solution/project

    下一篇: DateTime.TryParseExact won't parse what appears to be a valid date string