MSBuild发布.NET Core应用程序

26

我的配置是这样的:我有一个解决方案,里面有不同的dotnet4.6应用程序(服务)。现在我们在此解决方案中添加了一个dotnet core项目。我可以构建和调试它,但这并不会创建可执行文件。在Visual Studio中,我可以右键单击->发布...。我创建了两个配置文件(x86和x64),应该在/bin/Publish/x86或/x64中创建良好的二进制文件。在VS中,这很有效。该应用程序是自包含的,并且可以在不同的未准备好的机器上运行。

但现在我需要将该过程移动到构建服务器。我尝试使用dotnet publish,但最终因为解决方案的其他组件不是清洁的dotnet core而卡住了,所以我需要坚持使用MSBuild。

当前的尝试是:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe" NewProject\NewProject.csproj /p:DeployOnBuild=true /p:UsePublishProfile=true /p:PublishProfile=x64Profile

这表明它已成功构建,但我没有看到任何结果。如果删除所有属性并只调用msbuild和*.csproj,也不会有任何区别。它只会在bin/Debug中作为dll构建新项目,而不是exe。

我也尝试过p:PublishProfile="NewProject\Properties\PublishProfiles\x64Profile.pubxml"/p:PublishUrl="NewProject\bin\Publish\x64",但没有改变任何东西。

我在Stack Overflow上阅读了几篇文章,说VS不仅使用参数调用msbuild,还使用内部API调用。然而,我需要一个解决方案。我需要构建服务器创建可执行文件。有没有一种方法可以触发msbuild来创建它?

2个回答

28

噢,我已经搜索了2-3天。而且 - 像在 StackOverflow 上一样 - 在提问后不久,我自己找到了一个可行的答案。

简而言之:

Project.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
    <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>  
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <RootNamespace>Company.Toolset.Exporter</RootNamespace>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
    <RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
  </PropertyGroup>
  
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" />
...

MSBuild命令:

msbuild Project\Project.csproj -t:restore /t:Build;Publish /p:Configuration=Release /p:Platform=x86 /p:PublishProfile=x86Profile /p:OutputPath=bin/Publish/x86 (x64版本同理)

说明:

我想是dotnet build/publish命令要求我将TargetFrameworks更改为TargetFramework,但对于MSBuild来说这是错误的。而且由于该解决方案混合使用了dotnet core和dotnet framework,所以此项必须进行修复。

该命令需要添加<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>行。我将其添加到*.csproj文件中,因为我知道我只能在Windows上构建,而且我需要两个版本。

我不太清楚为什么需要这一行:<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" />,但如果没有它,发布和使用PublishProfiles将无法按预期工作。

帮助我达到目标的链接:(未排序)

https://github.com/Microsoft/msbuild/issues/1901

https://github.com/aspnet/vsweb-publish/issues/22

如何使用msbuild发布Web?

ASP.NET Core应用程序(.NET Framework)仅适用于Windows x64,在project.assets.json中出现错误

配置MSBuild输出路径


1
这只是我的直觉,但如果您使用<Project Sdk="Microsoft.NET.Sdk.Web">而不是使用库SDK,是否可以简化您的csproj? - TheXenocide
这个项目文件的第一行存在问题,就像其他评论所指出的那样。你也不应该修改它来使用 Microsoft.WebApplication.targets,因为这是 ASP.NET 4.x 项目的典型步骤。这可能会导致误导,因为 ASP.NET 和 ASP.NET Core 项目应该有所区别,并且不需要那么多的技巧。 - Lex Li

15

我也曾经遇到过一个噩梦,那就是Visual Studio IDE和dotnet publish命令构建的结果不一致,只有使用msbuild.exe才能解决这个问题。同时,使用/p:PublishProfiles=theXMLthatVSgenerates.xml也从未奏效,因此我必须将每个选项都拆分到msbuild命令行中。

以下是对我有效的方法:

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe" C:\Users\xxxx\Source\Repos\netcore-agent1\CoreAgent1\CoreAgent1.csproj /t:Restore;Rebuild;Publish /p:PublishSingleFile=True /p:SelfContained=True /p:PublishProtocol=FileSystem /p:Configuration=Release /p:Platform=x64 /p:TargetFrameworks=netcoreapp3.1 /p:PublishDir=bin\Release\netcoreapp3.1\publish\win-x64 /p:RuntimeIdentifier=win-x64 /p:PublishReadyToRun=False /p:PublishTrimmed=False

3
这几天一直在寻找这个解决方案 - 看起来“dotnet publish”与从Visual Studio发布不同。这解决了我的问题 - 非常感谢! - Rasmus Søborg
5
问题已解决。重要的是要指出,当使用“/p:SelfContained=True”时,还必须设置RuntimeIdentifier。例如:“/p:RuntimeIdentifier=win-x64” // 是的,你已经在选项列表中了。 - Christian Müller
哈哈,太真实了——Msbuild似乎忽略了PublishProfiles参数,继续做它自己的事情——不确定出了什么问题,但在VS之外,它不像广告上说的那样工作。 - torgabor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接