509

我是 Visual Studio 2010 中项目配置的新手,但我已经做了一些研究,但仍然无法完全解决这个问题。我有一个带有引用 C# DLL 的 C++ DLL 的 Visual Studio 解决方案。C# DLL 引用了一些其他 DLL,一些在我的项目中,一些在外部。当我尝试编译 C++ DLL 时,我收到以下警告:

警告 MSB3270:正在构建的项目的处理器架构“MSIL”与参考“[internal C# dll]”、“x86”的处理器架构不匹配。

它告诉我去配置管理器来调整我的架构。C# DLL 设置为平台目标 x86。如果我尝试将其更改为其他内容,例如 Any CPU,它会抱怨,因为它所依赖的外部 DLL 之一具有平台目标 x86。

当我查看配置管理器时,它将我的 C# DLL 的平台显示为 x86,将我的 C++ 项目的平台显示为 Win32。这似乎是正确的设置;当然,我不希望我的 C++ 项目的项目将平台设置为 x64,这是唯一的其他选项。

我在这里做错了什么?

4

20 回答 20

572

这个警告似乎是在新的 Visual Studio 11 Beta 和 .NET 4.5 中引入的,尽管我认为它以前可能是可能的。

首先,这实际上只是一个警告。如果您只是处理 x86 依赖项,它不应该有任何伤害。当您声明您的项目与“任何 CPU”兼容但您依赖于 x86 或 x64 的项目或 .dll 程序集时,Microsoft 只是试图警告您。因为您有 x86 依赖项,所以从技术上讲,您的项目与“任何 CPU”不兼容。要使警告消失,您实际上应该将项目从“任何 CPU”更改为“x86”。这很容易做到,这里是步骤。

  1. 转到构建|配置管理器菜单项。
  2. 在列表中找到您的项目,在平台下它会显示“任何 CPU”
  3. 从下拉列表中选择“任何 CPU”选项,然后选择<New..>
  4. 在该对话框中,从“New Platform”下拉列表中选择 x86,并确保在“Copy settings from”下拉列表中选择“Any CPU”。
  5. 点击确定
  6. 您需要为 Debug 和 Release 配置选择 x86。

这将使警告消失,并表明您的程序集或项目现在不再与“任何 CPU”兼容,但现在特定于 x86。如果您正在构建具有 x64 依赖项的 64 位项目,这也适用;您只需选择 x64 即可。

另请注意,如果项目是纯 .NET 项目,通常可以与“任何 CPU”兼容。仅当您引入针对特定处理器架构的依赖项(第 3 方 dll 或您自己的 C++ 托管项目)时,才会出现此问题。

于 2012-04-17T18:04:13.760 回答
153

这是一个非常顽固的警告,虽然它是一个有效的警告,但在某些情况下,由于使用 3rd 方组件和其他原因,它无法解决。我有一个类似的问题,除了警告是因为我的项目平台是 AnyCPU 并且我正在引用为 AMD64 构建的 MS 库。顺便说一下,这是在 Visual Studio 2010 中,似乎是通过安装 VS2012 和 .Net 4.5 引入的。

由于我无法更改我引用的 MS 库,并且我知道我的目标部署环境将永远是 64 位,所以我可以放心地忽略这个问题。

警告呢?微软在回应Connect 报告时发布了一个选项是禁用该警告。只有非常了解您的解决方案架构并且您完全了解您的部署目标并且知道它在开发环境之外并不是真正的问题时,您才应该这样做。

您可以编辑项目文件并添加此属性组和设置以禁用警告:

<PropertyGroup>
  <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
于 2012-10-01T11:36:52.357 回答
67

一个好的经验法则是“打开 DLL,关闭 EXE”,即:

  • EXE通过指定 x86 或 x64 以操作系统为目标。
  • DLL保持打开状态(即 AnyCPU),因此它们可以在 32 位或 64 位进程中实例化。

当您将 EXE 构建为 AnyCPU 时,您所做的就是将决定使用哪个进程位数的决定推迟到操作系统,这将使 EXE 按自己的喜好进行 JIT。也就是说,x64 操作系统将创建一个 64 位进程,x86 操作系统将创建一个 32 位进程。

将 DLL 构建为 AnyCPU 使它们与任一进程兼容。

有关程序集加载的细节的更多信息,请参见此处。执行摘要的内容如下:

  • AnyCPU – 根据调用进程加载为 x64 或 x86 程序集
  • x86 – 加载为 x86 程序集;不会从 x64 进程加载
  • x64 – 加载为 x64 程序集;不会从 x86 进程加载
于 2012-11-13T23:19:03.957 回答
24

C# DLL 设置为平台目标 x86

这是一个问题,DLL实际上并不能选择进程的位数。这完全由 EXE 项目决定,这是第一个加载的程序集,因此它的平台目标设置是计算和设置进程位数的那个。

DLL 没有选择,它们需要与进程位数兼容。如果它们不是,那么当您的代码尝试使用它们时,您将得到一个带有 BadImageFormatException 的大 Kaboom。

因此,DLL 的一个很好的选择是 AnyCPU,因此它们可以以任何方式工作。这对 C# DLL 很有意义,它们确实可以工作。但可以肯定的是,不是您的 C++/CLI 混合模式 DLL,它包含非托管代码,只有当进程在 32 位模式下运行时才能正常工作。您可以让构建系统生成有关此的警告。这正是你得到的。只是警告,它仍然可以正常构建。

只是解决问题。将 EXE 项目的平台目标设置为 x86,它不会与任何其他设置一起使用。并且只需将所有 DLL 项目保存在 AnyCPU 上。

于 2012-04-17T00:57:02.303 回答
8

我得到了同样的警告,我这样做了:

  1. 卸载项目
  2. 编辑项目属性,即 .csproj
  3. 添加以下标签:

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
    
  4. 重新加载项目

于 2016-11-03T13:19:33.803 回答
5

我今天遇到了这个问题,只是查看 Visual Studio 中的构建配置并没有帮助,因为它显示了未构建的项目和引用的项目的任何 CPU。

然后我查看了引用项目的 csproj 并发现了这个:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>

不知何故,这个 PlatformTarget 是在配置更改的中间添加的,IDE 似乎没有看到它。

从引用的项目中删除这一行解决了我的问题。

于 2017-03-31T12:58:10.590 回答
4

使用https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-example

  • Directory.Build.props文件添加到您的解决方案文件夹
  • 将其粘贴在其中:
<Project>
 <PropertyGroup>
   <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
 </PropertyGroup>
</Project>
于 2019-11-06T15:02:43.177 回答
3

除了 David Sacks 的回答之外,您可能还需要转到为您提供这些警告的项目的Build选项卡Project Properties并设置Platform Target为。x86尽管您可能希望如此,但此设置似乎与配置管理器中的设置并不完全同步。

于 2014-05-04T20:15:15.683 回答
3

如果您的 C# DLL 具有基于 x86 的依赖项,那么您的 DLL 本身将必须是 x86。我真的没有办法解决这个问题。VS 抱怨将其更改为(例如)x64,因为 64 位可执行文件无法加载 32 位库。

我对 C++ 项目的配置有点困惑。为构建提供的警告消息表明它针对 AnyCPU,因为它报告它针对的平台是 [MSIL],但您指出该项目的配置实际上是 Win32。本机 Win32 应用程序不应涉及 MSIL - 尽管如果它与 C# 库交互,它可能需要启用 CLR 支持。所以我认为在信息方面存在一些差距。

我能否恭请您查看并发布项目的确切配置以及它们如何相互关联的更多细节?如果可能的话,很乐意提供进一步的帮助。

于 2012-04-23T19:11:59.793 回答
2

对于 C# 项目,x86 的目标就像它听起来的那样。它说这个程序集只支持 x86 架构。对于 x64 也是如此。另一方面,任何 CPU 都表示我不在乎哪种架构,我都支持。那么,接下来的 2 个问题是(1)使用这些 dll 的可执行文件的配置是什么?(2) 位数是多少您的操作系统/计算机?我问的原因是因为如果您的可执行文件被编译为以 64 位运行,那么它也需要所有依赖项才能在 64 位模式下运行。您的 Any CPU 程序集应该能够被加载,但也许它引用了一些只能在 x86 配置中运行的其他依赖项。如果您计划在 64 位模式下运行可执行文件,请检查所有依赖项和依赖项的依赖项,以确保一切都是“任何 CPU”或“x64”。否则,你会有问题。

在许多方面,Visual Studio 并不容易编译任何 CPU 和各种依赖于体系结构的程序集的混合体。这是可行的,但它通常要求必须为 x86 和 x64 分别编译一个原本是“任何 CPU”的程序集,因为某处的某些依赖项有两个版本。

于 2012-04-11T21:11:06.743 回答
1

对于我的项目,我需要能够构建到 x86 和 x64。这样做的问题是,每当您在使用一个引用时添加引用,当您构建另一个引用时它就会抱怨。

我的解决方案是手动编辑 *.csproj 文件,以便像这样的行:

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=x86"/>

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64"/>

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"/>

改成这样:

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral"/>
于 2014-02-06T18:58:47.280 回答
1

我之前也遇到过类似的问题,特别是在向现有 x64 解决方案(如 SharePoint)添加测试解决方案时。就我而言,这似乎与某些项目模板默认添加为某些平台这一事实有关。

这是通常对我有用的解决方案:在配置管理器中将所有内容设置为正确的平台(活动配置下拉菜单,通常说调试,是一个很好的方法)和项目平台(在项目属性中),然后构建,然后将所有内容设置回 AnyCPU。有时我必须删除并重新添加一些依赖项(每个项目的属性中的 DLL),有时必须更改“在 32 位或 64 位进程中运行测试”(双击 Local.testsettings 并转到主机)。

在我看来,这只是设置一些东西然后将其设置回去,但幕后可能还有更多我没有看到的事情。不过,它在过去对我来说相当一致。

于 2012-11-09T22:26:00.363 回答
1

我有类似的问题,它是由 MS UNIT Test DLL 引起的。我的 WPF 应用程序编译为 x86,但单元测试 DLL(引用的 EXE 文件)为“任何 CPU”。我更改了要为 x86 编译的单元测试 DLL(与 EXE 相同),它已被重新处理。

于 2014-02-25T12:01:22.930 回答
1

由于 f.csproj 是基于命令构建的,因此您可能还会收到 MS Fakes 程序集的此警告,该程序集不容易解决。幸运的是,Fakes xml 允许您在其中添加它

于 2015-04-24T15:50:51.457 回答
0

我解决了这个警告,将“配置管理器”更改为发布(混合平台)。

于 2015-04-15T15:17:21.000 回答
0

我的构建中有一个非常相似的警告。我的项目设置为面向 .NET 4.5,在构建服务器上安装了 Windows 8.1 SDK(用于 .NET 4.5.1)。在将我的项目更新为 .NET 4.5.1 之后(对我来说这不是问题,是一个全新的应用程序),我不再收到警告......

于 2015-03-10T11:18:44.833 回答
0

编译 SQL Server 2012 SP1 SSIS 管道脚本任务时,我在 Visual Studio 2012 中收到此警告 - 直到我安装了 SQL Server 2012 SP2。

于 2015-05-20T15:57:55.113 回答
0

我在 SQLite 打开连接时遇到了同样的问题,并且使用 Nuget 并安装了项目中使用的组件(SQLite)修复了它!尝试以这种方式安装您的组件并检查结果

于 2017-09-18T07:09:47.977 回答
0

只想为那些在这里找不到答案的人发帖解决了他们的问题。

运行应用程序时,请确保正确设置了解决方案平台下拉菜单。我的在 x86 上,这反过来又导致了我这个问题。

于 2020-08-30T20:55:21.543 回答
-1

There should be a way to make a .NET EXE/DLL AnyCPU, and any unmanaged DLLs it depends on compiled both with x86 and x64, both bundled perhaps with different filenames and then the .NET module dynamically loading the correct one based on its runtime processor architecture. That would make AnyCPU powerful. If the C++ DLL only supports x86 or x64 then AnyCPU is of course pointless. But the bundling both idea I have yet to see implemented as the configuration manager does not even provide a means to build the same project twice with a different configuration/platform for multiple bundling allowing AnyCPU or even other concepts like any configuration to be possible.

于 2013-10-22T17:40:17.150 回答