使用MSBuild.exe发布Net5.0控制台应用程序,因为dotnet无法工作

5
如果可能的话,我希望您能为以下问题提供帮助:我尝试通过命令行发布我的.NET 5.0控制台应用程序,因为我必须将其包含在ansible脚本中,以便能够从jenkins进行构建和部署,并且当我尝试以下命令时: dotnet publish --configuration Release -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true --runtime win-x86 --framework net5.0 我收到以下错误: C:\Program Files\dotnet\sdk\5.0.102\Microsoft.Common.CurrentVersion.targets(2744,5): error : MSB4803: 任务“ResolveComReference”不受MSBuild的.NET Core版本支持。请使用MSBuild的.NET Framework版本。有关详细信息,请参见 https://aka.ms/msbuild/MSB4803。[I:\workspaceVS\net50\ConsoleCoreApp1\ConsoleCoreApp1.csproj] 据我所知,这是由于dotnet无法发布具有COM引用的项目造成的。我有一个.dll文件作为API,用于访问远程服务器以获取数据。我需要先使用regsvr32命令注册这个.dll文件,然后才能在我的项目中引用它。
如果我尝试使用VS2019中的发布功能,则可以正常工作,但我不想在我的AWS机器上安装VS2019,我只想安装像MSBuild这样的工具,通过运行ansible playbook中的命令来构建和发布我的应用程序(而不是打开VS2019并点击按钮以发布应用程序)。
解决方案是使用MSBuild。但是...我不知道怎么做。
现在,在尝试以下命令后: dotnet msbuild ConsoleCoreApp1.csproj /t:publish /p:Configuration=Release /p:TargetFramework=net5.0 /p:SelfContained=true /p:PublishTrimmed=True /p:PublishReadyToRun=True /p:RuntimeIdentifier=win-x86 /p:PublishDir=bin\Release 我收到相同的错误: C:\Program Files\dotnet\sdk\5.0.102\Microsoft.Common.CurrentVersion.targets(2744,5): error : MSB4803: 任务“ResolveComReference”不受MSBuild的.NET Core版本支持。请使用MSBuild的.NET Framework版本。有关详细信息,请参见 https://aka.ms/msbuild/MSB4803。[I:\workspaceVS\net50\ConsoleCoreApp1\ConsoleCoreApp1.csproj] 解决方法是直接使用MSBuild,例如:

& 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe' /t:publish /p:Configuration=Release /p:TargetFramework=net5.0 /p:SelfContained=true /p:PublishTrimmed=True /p:PublishReadyToRun=True /p:RuntimeIdentifier=win-x86 /p:PublishDir=bin\Release

这个命令可以正常运行,但存在一个问题,它无法发布应用程序为单个 .exe 文件。

有任何想法吗?谢谢!

-------------------- 编辑 --------------------

能够正常工作的命令:

enter image description here

无法正常工作的命令:

我将 msbuild 添加到了路径中,现在如果只运行以下命令msbuild /t:publish /p:Configuration=Release /p:TargetFramework=net5.0,我会得到一个有效的应用程序,但是当我尝试运行它时,会出现以下错误:

    Unhandled exception. System.Runtime.InteropServices.COMException (0x80040154): Retrieving the COM class factory for component with CLSID {CE92C3B9-9A93-40E1-85AB-6A49170AEF7F} failed due to the following error: 80040154 Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)).
   at ConsoleApp1.Service1..ctor(String[] args) in I:\workspaceVS\net50\ConsoleCoreApp1\Service1.cs:line 24
   at ConsoleCoreApp1.Program.Main(String[] args) in I:\workspaceVS\net50\ConsoleCoreApp1\Program.cs:line 7

这是因为我的.dll API只支持win32位,所以我需要使用win-x86标志进行编译。
但是使用以下命令进行发布:msbuild /t:publish /p:Configuration=Release /p:TargetFramework=net5.0 /p:SelfContained=true /p:PublishTrimmed=True /p:PublishReadyToRun=True /p:RuntimeIdentifier=win-x86 -p:PublishSingleFile=true,会出现以下错误:
Build FAILED.

"I:\workspaceVS\net50\ConsoleCoreApp1\ConsoleCoreApp1.csproj" (publish target) (1) ->
(ResolvePackageAssets target) ->
  C:\Program Files\dotnet\sdk\5.0.102\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(241,5): error NETSDK1047: A
ssets file 'I:\workspaceVS\net50\ConsoleCoreApp1\obj\project.assets.json' doesn't have a target for 'net5.0/win-x86'. Ensure that restore has
run and that you have included 'net5.0' in the TargetFrameworks for your project. You may also need to include 'win-x86' in your project's Run
timeIdentifiers.

好的,通过修改ConsoleCoreApp1.csproject文件并添加<RuntimeIdentifier>win-x86</RuntimeIdentifier>,我成功解决了最后一个错误问题:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <RuntimeIdentifier>win-x86</RuntimeIdentifier>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <Prefer32Bit>true</Prefer32Bit>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
    <Prefer32Bit>true</Prefer32Bit>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

  <ItemGroup>
    <COMReference Include="GV8APILib.dll">
      <WrapperTool>tlbimp</WrapperTool>
      <VersionMinor>1</VersionMinor>
      <VersionMajor>1</VersionMajor>
      <Guid>0a67e301-3ecb-47be-bba9-dc67ff219358</Guid>
      <Lcid>0</Lcid>
      <Isolated>false</Isolated>
    </COMReference>
  </ItemGroup>

  <ItemGroup>
    <Folder Include="FileReading\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
    <PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
    <PackageReference Include="NLog" Version="4.7.7" />
    <PackageReference Include="NLog.Config" Version="4.7.7" />
    <PackageReference Include="NLog.Schema" Version="4.7.7" />
    <PackageReference Include="RabbitMQ.Client" Version="6.2.1" />
    <PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
    <PackageReference Include="System.Text.Json" Version="5.0.1" />
  </ItemGroup>


  <ItemGroup>    
    <None Update="NLog.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="NLog.xsd">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Others\___.key">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Others\___.p12">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Others\rmq___.uat.key">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Others\rmq___.uat.p12">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Others\rmq___.uat.pem">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\AllOrders.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\Companies.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\DealsOrders - RequestAllDefinitions.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\DealsOrders.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\RequestHistTrades.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\InstrumentDefinitionsQuery.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\Orders.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\QueryOutput.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="XMLRequest\SequenceItemsQuery.xml">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="Libraries\___.GvApi.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Libraries\System.Threading.Tasks.Dataflow.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Libraries\___.GvApi.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="Libraries\___.GvApi.Managed.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>


目前无法将所有文件打包成一个 .exe 文件,这仍然是一个问题。谢谢!

你使用的是哪个版本的Net?如果你使用的是4.7.2之前的旧版本,那么在尝试发布到Core时会出现问题。而在4.7.2之后的版本中,你可以编译为Net或Core。 - jdweng
我正在使用 .net 5.0。在我的 CSPROJ 文件 (.csproj) 中,我使用以下代码:<TargetFramework>net5.0</TargetFramework>。此外,在使用命令行工具时,我使用 /p:TargetFramework=net5.0。 - R13mus
当你发布时,VS会创建一个setup.exe文件夹,就像商业软件一样,它只更新Windows DLL并不安装VS。运行setup.dll的一部分是将机器上的Windows DLL更新为与构建DLL匹配的版本。不确定为什么您不想发布。 - jdweng
据我所知,COM是Windows特定的技术,因此您应该使用net5.0-windows而不是net5.0。https://devblogs.microsoft.com/dotnet/announcing-net-5-0/#net-5-0-target-framework - JL0PD
如果我尝试使用net5.0-windows,我会得到以下错误 - 构建失败。"I:\workspaceVS\net50\ConsoleCoreApp1\ConsoleCoreApp1.csproj" (发布目标) (1) -> (ResolvePackageAssets 目标) -> C:\Program Files\dotnet\sdk\5.0.102\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(241,5): 错误 NETSDK1005: 资产文件 'I:\workspaceVS\net50\ConsoleCoreApp1\obj\project.assets.json' 没有针对 'net5.0-windows' 的目标。确保已运行还原,并且已将 'net5.0-windows' 包含在项目的 TargetFrameworks 中。 - R13mus
2个回答

3

实际上,正如你所说,使用msbuild -t:publish是最好的方法,而dotnet publish无法处理COM参考。

并且你应该改用命令行,对你的命令行进行了一些修改:

msbuild /t:publish /p:Configuration=Release /p:TargetFramework=net5.0 /p:SelfContained=true /p:PublishTrimmed=True /p:PublishReadyToRun=True /p:RuntimeIdentifier=win-x86  -p:PublishSingleFile=true

您需要添加-p:PublishSingleFile=true

或者,您可以参考此类似问题的建议。


现在,当尝试使用附加标志 -p:PublishSingleFile=true 运行时(顺便问一下是 -p: 还是 /p:),我收到以下错误信息: error NETSDK1047:'I:\workspaceVS\net50\ConsoleCoreApp1\obj\project.assets.json' 资产文件没有针对 'net5.0/win-x86' 的目标。请确保已运行还原操作,并且已将 'net5.0' 包含在项目的 TargetFrameworks 中。 - R13mus
使用 msbuild -t:restore,publish xxxx 命令,是否成功? - Mr Qian
运行以下命令:msbuild /t:restore /t:publish /p:Configuration=Release /p:TargetFramework=net5.0 /p:SelfContained=true /p:PublishTrimmed=True /p:PublishReadyToRun=True /p:RuntimeIdentifier=win-x86 -p:PublishSingleFile=true,结果为:“(restore;publish target) (1) -> (GenerateSingleFileBundle target) -> ...\targets\Microsoft.NET.Publish.targets(1016,5): error MSB4018: 任务“GenerateBundle”意外失败。[...] ...\targets\Microsoft.NET.Publish.targets(1016,5): error MSB4018: System.ArgumentException: 输入规范无效:发现多个具有相同BundleRelativePath的条目。” - R13mus
如果我移除 '-p:PublishSingleFile=true' 这个参数,它就能工作,只是我得到的不是单一的文件,而是一个包含很多 .dll 文件等的文件夹。 - R13mus
此外,请检查您是否在项目中使用了此nuget包,链接为https://github.com/dotnet/runtime/issues/3735。若能与我们分享您的csproj文件将更有帮助。 - Mr Qian
显示剩余2条评论

2
以下是适用于我的.NET 6.0项目的msbuild命令和选项:
msbuild -property:Configuration=Release;IncludeAllContentForSelfExtract=true;Platform="Any CPU";PublishReadyToRun=true;PublishSingleFile=true;PublishTrimmed=True;Runtimeidentifier=win-x64;SelfContained=true -restore -target:publish SingleFileApp.sln

这个单文件应用程序已经发布在:

bin\Release\net6.0\win-x64\publish

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