Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 在Visual Studio中生成时有条件地使用32/64位引用_.net_Visual Studio_64 Bit_32bit 64bit - Fatal编程技术网

.net 在Visual Studio中生成时有条件地使用32/64位引用

.net 在Visual Studio中生成时有条件地使用32/64位引用,.net,visual-studio,64-bit,32bit-64bit,.net,Visual Studio,64 Bit,32bit 64bit,我有一个以32/64位构建的项目,它具有相应的32/64位依赖项。我希望能够切换配置并使用正确的引用,但我不知道如何告诉VisualStudio使用与体系结构相关的依赖项 也许我做得不对,但我希望能够在配置下拉列表中在x86和x64之间切换,并使引用的DLL具有正确的位。AFAIK,如果您的项目需要32位或64位特定的引用(即COM互操作程序集),如果您对手动编辑.csproj文件不感兴趣,则必须创建单独的32位和64位项目 我应该注意到以下解决方案未经测试,但应该可以工作。如果您愿意手动编辑.

我有一个以32/64位构建的项目,它具有相应的32/64位依赖项。我希望能够切换配置并使用正确的引用,但我不知道如何告诉VisualStudio使用与体系结构相关的依赖项


也许我做得不对,但我希望能够在配置下拉列表中在x86和x64之间切换,并使引用的DLL具有正确的位。

AFAIK,如果您的项目需要32位或64位特定的引用(即COM互操作程序集),如果您对手动编辑.csproj文件不感兴趣,则必须创建单独的32位和64位项目

我应该注意到以下解决方案未经测试,但应该可以工作。如果您愿意手动编辑.csproj文件,那么您应该能够通过单个项目获得所需的结果。.csproj文件只是一个MSBuild脚本,因此要获得完整引用,请查看。在编辑器中打开.csproj文件后,找到
元素。您应该能够将这些元素分成3个不同的引用:非平台特定的引用、x86特定的引用和x64特定的引用

下面的示例假设您的项目配置了名为“x86”和“x64”的目标平台


..\..\lib\x86\MyComAssembly.Interop.dll
..\..\lib\x64\MyComAssembly.Interop.dll
现在,当您将项目/解决方案构建配置设置为以x86或x64平台为目标时,它应该在每种情况下都包含正确的引用。当然,您需要使用
元素。您甚至可以在添加x86和x64引用的地方设置虚拟项目,然后将必要的
元素从这些虚拟项目文件复制到“真实”项目文件中


编辑1

这里有一个指向公共MSBuild项目项的链接,我在最初的帖子中意外遗漏了该项目项:

这是我在以前的项目中所做的工作,需要手动编辑.csproj文件。您还需要为不同的二进制文件创建单独的目录,最好是彼此的兄弟目录,并使用与目标平台相同的名称

向项目添加单个平台的引用后,在文本编辑器中打开.csproj。在
元素中的第一个
元素之前,添加以下代码,这将有助于确定您在哪个平台上运行(和构建)


x86
AMD64
然后,对于特定于平台的引用,进行如下更改:

<ItemGroup>
  <Reference Include="Leadtools, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.dll</HintPath>
  </Reference>
  <Reference Include="Leadtools.Codecs, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.Codecs.dll</HintPath>
  </Reference>
  <Reference Include="Leadtools.ImageProcessing.Core, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.ImageProcessing.Core.dll</HintPath>
  </Reference>
  <Reference Include="System" />
  <Reference Include="System.Core" />
  <Reference Include="System.Data.Entity" />
  <!--  Other project references -->
</ItemGroup>

错误的
..\..\Lib\Leadtools\$(当前平台)\Leadtools.dll
错误的
..\..\Lib\Leadtools\$(当前平台)\Leadtools.Codecs.dll
错误的
..\..\Lib\Leadtools\$(当前平台)\Leadtools.ImageProcessing.Core.dll
请注意前面定义的
$(CurrentPlatform)
属性的使用。相反,您可以使用条件来表示要为哪个平台包含哪些程序集。您还需要:

    替换“代码> $(Purror OrthyRealW5632)<代码>和<代码> $(PractRoWorkStices)<代码> > <代码>(平台)< /> >只考虑项目的目标平台
  • 更改平台确定逻辑以适合当前机器,这样您就不会构建/引用64位二进制文件以在32位平台上执行

我最初是为工作中的一个内部Wiki编写的,但是,如果您对详细的分步说明感兴趣,我已经对其进行了修改并发布了。

我在我的项目中引用了x86 DLL,位于例如。\component\v3\u NET4中。x86/x64的特定DLL分别位于名为“x86”和“x64”的子文件夹中

然后,我使用一个预构建脚本,根据$(PlatformName)将适当的DLL(x86/x64)复制到引用的文件夹中


适用于我。

您可以为项目文件中的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>

..\DLLName.dll
{AAAAAA-000000-BBBB-CCCC-tttttttt}
MyOtherProject

我也面临同样的问题,花了相当长的时间寻找一个像样的解决方案。大多数人都提供对VisualStudio解决方案文件的手动编辑,这非常繁琐,在以后在VisualStudioGUI中浏览这些编辑过的文件时容易出错和混淆。当我已经放弃的时候,解决方案自己就出现了。这与米克在上面的回答中所建议的非常相似

在AccountManager中,我像往常一样为x86和x64平台创建了两个单独的构建目标。接下来,我在项目中添加了对x86程序集的引用。在这一点上,我认为该项目只针对x86版本进行配置,并且永远不会针对x64配置进行构建,除非我按照上面Hugo的建议对其进行手动编辑

过了一段时间,我最终忘记了限制,意外地启动了x64构建。当然,构建失败了。但重要的是我收到的错误信息。错误消息告诉我,作为我的解决方案的x64生成目标的文件夹中缺少名为与我引用的x86程序集完全相同的程序集

注意到这一点,我已手动将正确的x64程序集复制到此目录中。荣誉我的x64构建奇迹般地成功,找到并隐式链接了正确的程序集。修改我的解决方案以将x64程序集的生成目标目录设置到此文件夹只需几分钟。在这些步骤之后,解决方案将自动为x86和x64构建,而无需任何手动操作
<ItemGroup>
  <Reference Include="Leadtools, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.dll</HintPath>
  </Reference>
  <Reference Include="Leadtools.Codecs, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.Codecs.dll</HintPath>
  </Reference>
  <Reference Include="Leadtools.ImageProcessing.Core, Version=16.5.0.0, Culture=neutral, PublicKeyToken=9cf889f53ea9b907, processorArchitecture=x86">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>..\..\Lib\Leadtools\$(CurrentPlatform)\Leadtools.ImageProcessing.Core.dll</HintPath>
  </Reference>
  <Reference Include="System" />
  <Reference Include="System.Core" />
  <Reference Include="System.Data.Entity" />
  <!--  Other project references -->
</ItemGroup>
xcopy /s /e /y "$(SolutionDir)..\component\v3_NET4\$(PlatformName)\*" "$(SolutionDir)..\component\v3_NET4"
 <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>
AppDomain.CurrentDomain.AssemblyResolve += TryResolveArchitectureDependency;
/// <summary>
/// Event Handler for AppDomain.CurrentDomain.AssemblyResolve
/// </summary>
/// <param name="sender">The app domain</param>
/// <param name="resolveEventArgs">The resolve event args</param>
/// <returns>The architecture dependent assembly</returns>
public static Assembly TryResolveArchitectureDependency(object sender, ResolveEventArgs resolveEventArgs)
{
    var dllName = resolveEventArgs.Name.Substring(0, resolveEventArgs.Name.IndexOf(","));

    var anyCpuAssemblyPath = $".\\{dllName}.dll";

    var architectureName = System.Environment.Is64BitProcess ? "x64" : "x86";

    var assemblyPath = $".\\{architectureName}\\{dllName}.dll";

    if (File.Exists(assemblyPath))
    {
        return Assembly.LoadFrom(assemblyPath);
    }

    return null;
}