且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将 dotnetcore 项目迁移到 1.0.4 后出现“dotnet build"错误

更新时间:2022-10-14 23:08:55

包含在 .NET Core CLI 中的 MSBuild .NET Core 构建能够在 Windows 机器上构建经典项目,只要它们面向 .NET Framework >= 4.0,安装了参考程序集并且没有使用特殊的目标/任务.

在您的情况下,您尝试编译与主机 MSBuild 实例架构不同的资源.从即将推出的 2.0 工具开始,这在基于 SDK 的项目中得到解决,但经典项目依赖 MSBuild 使用不同的 CLR 启动附加进程 - 这在 .NET Core 上不受支持.

解决这个问题的简单方法是不使用 dotnet 命令来恢复/构建解决方案,而是使用与 Visualstudio 使用开发人员命令提示符.(例如 => msbuild/t:Restoremsbuildmsbuild/t:Publish/p:Configuration=Release 等).>

另一种解决方法是编辑有问题的 csproj 文件,将其添加到旧"项目中的 :

<GenerateResourceMSBuildArchitecture>CurrentArchitecture</GenerateResourceMSBuildArchitecture><GenerateResourceMSBuildRuntime>CurrentRuntime</GenerateResourceMSBuildRuntime></PropertyGroup>

MSBuild 的 GitHub 存储库上有一个关于此问题的问题.

I've been trying to run the dotnet build command on a migrated .net core project (from 1.0.0-preview2-003131 to 1.0.4). I followed the steps for migrating the project mentioned here, and the solution builds using Visual Studio 2017. However, using the dotnet CLI command 'dotnet build' gives me the following error:

C:Program Filesdotnetsdk1.0.4Microsoft.Common.CurrentVersion.targets(2867,5): error MSB4216: Could not run the "GenerateResource" task because MSBuild could not create or connect to a task host with runtime "CLR4" and architecture "x86". Please ensure that (1) the requested runtime and/or architecture are available on the machine, and (2) that the required executable "C:Program Filesdotnetsdk1.0.4MSBuild.exe" exists and can be run.

I have migrated a couple of other services earlier, and after sorting out a couple of package dependencies, the CLI commands worked just fine. I checked the sdk location mentioned in the error, and I couldn't find MSBuild.exe (I did find the MSBuild.dll and the MsBuild.deps file though). I need the CLI commands to work for the CI/CD setup that I have. Any help with deciphering and fixing this error is much appreciated.

System Details:

  1. Visual Studio 2017 Community
  2. dotnet --version --> 1.0.4

The migration steps I followed:

  1. Changed the sdk version in global.json
  2. Ran the dotnet migrate command
  3. Opened the solution in VS 2017 and built it. The build was successful.

Edit: I assumed that this was a dotnet core project. Apparently (even before running the dotnet migrate command), one of the projects inside this solution was already targeting .Net 4.5.2. The relevant .csproj file is below:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVersion)Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{C092FA80-6783-4282-A3B0-C589FB3027F8}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Siemens.PLM.Teamcenter.DatasetService.PLDrive</RootNamespace>
    <AssemblyName>DatasetService.PLDrive</AssemblyName>
    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <WarningLevel>4</WarningLevel>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <PublishUrl>publish</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Disk</InstallFrom>
    <UpdateEnabled>false</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>true</MapFileExtensions>
    <ApplicationRevision>0</ApplicationRevision>
    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
    <IsWebBootstrapper>false</IsWebBootstrapper>
    <UseApplicationTrust>false</UseApplicationTrust>
    <BootstrapperEnabled>true</BootstrapperEnabled>
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>binDebug</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>binRelease</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="MimeTypesMap, Version=1.0.1.0, Culture=neutral, PublicKeyToken=1b320cc08ad5aa89, processorArchitecture=MSIL">
      <HintPath>....packagesMimeTypesMap.1.0.1lib
et451MimeTypesMap.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>....packagesNewtonsoft.Json.9.0.1lib
et45Newtonsoft.Json.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
    <ApplicationDefinition Include="App.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </ApplicationDefinition>
    <Page Include="AppToolbar.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="ConsolePage.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="ListPage.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="MainPage.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="MainWindow.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
    <Compile Include="App.xaml.cs">
      <DependentUpon>App.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="AppToolbar.xaml.cs">
      <DependentUpon>AppToolbar.xaml</DependentUpon>
    </Compile>
    <Compile Include="DatasetList.cs" />
    <Compile Include="ListPage.xaml.cs">
      <DependentUpon>ListPage.xaml</DependentUpon>
    </Compile>
    <Compile Include="MessageTypeEnum.cs" />
    <Compile Include="ConsolePage.xaml.cs">
      <DependentUpon>ConsolePage.xaml</DependentUpon>
    </Compile>
    <Compile Include="DatasetService.cs" />
    <Compile Include="FileIndex.cs" />
    <Compile Include="FileWatcher.cs" />
    <Compile Include="MainPage.xaml.cs">
      <DependentUpon>MainPage.xaml</DependentUpon>
    </Compile>
    <Compile Include="MainWindow.xaml.cs">
      <DependentUpon>MainWindow.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="MessageListener.cs" />
    <Compile Include="PropertiesAssemblyInfo.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="PropertiesResources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="PropertiesSettings.Designer.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Settings.settings</DependentUpon>
      <DesignTimeSharedInput>True</DesignTimeSharedInput>
    </Compile>
    <EmbeddedResource Include="PropertiesResources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <None Include="packages.config" />
    <None Include="PropertiesSettings.settings">
      <Generator>SettingsSingleFileGenerator</Generator>
      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
    </None>
    <AppDesigner Include="Properties" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
  </ItemGroup>
  <ItemGroup>
    <BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
      <Visible>False</Visible>
      <ProductName>Microsoft .NET Framework 4.5.2 %28x86 and x64%29</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.5 SP1</ProductName>
      <Install>false</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

The original solution compiles and builds without any problems. I'm a bit new to this, but I'm a bit confused as to how a solution which has projects targeting two separate vesions of dotnet compiles (and why, on migrating, the build process fails). Should I be running the migrate commands separately? (only on .xproj projects)?

The .NET Core build of MSBuild that is included in the .NET Core CLI is capable of building classic projects on windows machines as well as long as they target .NET Framework >= 4.0, reference assemblies are installed and no special targets / tasks are used.

In your case, you tried to compile a resource with a different architecture than the host MSBuild instance is. This is worked around in SDK-based projects beginning in the upcoming 2.0 tools but classic projects rely on MSBuild to launch an additional process using a different CLR - which is not supported on .NET Core.

The easy way to work around it is to not use the dotnet commands to restore / build the solution, but their msbuild equivalents using the msbuild.exe installed with visual studio using the developer command prompt. (e.g. => msbuild /t:Restore, msbuild, msbuild /t:Publish /p:Configuration=Release etc.).

Another workaround would be to edit the problematic csproj file to add this to the <Project> in the "old" project:

<PropertyGroup Condition="'$(MSBuildRuntimeType)' == 'Core'">
  <GenerateResourceMSBuildArchitecture>CurrentArchitecture</GenerateResourceMSBuildArchitecture>
  <GenerateResourceMSBuildRuntime>CurrentRuntime</GenerateResourceMSBuildRuntime>
</PropertyGroup>

There is an issue on MSBuild's GitHub repo about this problem.