dotnet发布包括额外的文件

时间:2018-03-30 10:48:24

标签: .net .net-core .net-core-2.0

我有一个netcore应用程序取决于我的自定义项目。因为我无法直接引用它,所以我编写了将我的文件复制到输出的postbuildevents:

xcopy "$(SolutionDir)Ethereum.Contracts\bin\$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I
xcopy "$(SolutionDir)Ethereum.Contracts\bin\$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I

我在构建和运行项目时工作正常,但是当运行publish命令时,它不会包含这些文件。

怎么做?我也试过this approach,但AddPayloadsFolder没有被调用。

我的csproj

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\..\Dependencies\Dependencies.csproj" />
  </ItemGroup>

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="log4net.config">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="xcopy &quot;$(SolutionDir)Ethereum.Contracts\bin\$(ConfigurationName)\*.abi&quot; &quot;$(TargetDir)&quot; /Y /I&#xA;&#xA;&#xD;&#xA;xcopy &quot;$(SolutionDir)Ethereum.Contracts\bin\$(ConfigurationName)\*.bin&quot; &quot;$(TargetDir)&quot; /Y /I" />
  </Target>

  <Target Name="AddPayloadsFolder" AfterTargets="AfterPublish">
    <Exec Command="xcopy &quot;$(TargetDir)\*.abi&quot; &quot;$(PublishDir)&quot; /Y /I&#xA;&#xA;&#xD;&#xA;xcopy &quot;$(TargetDir)\*.bin&quot; &quot;$(PublishDir)&quot; /Y /I" />
  </Target>

</Project>

2 个答案:

答案 0 :(得分:1)

启动dotnet publish命令时,未定义$(SolutionDir)个宏。结果xcopy启动时源路径不正确。

缺少解决方案宏的问题是described here,它仍处于打开状态。我不确定它是否会被修复,因为$(SolutionDir)是特定于IDE的宏。

要解决您的问题,您可以通过切换$(SolutionDir)dotnet publish宏的值传递给/p命令:

  

dotnet publish -c Release -r win-x64   / P:SolutionDir = “d:\项目\ SolutionDir”

您还应该在$(SolutionDir)宏之后添加反斜杠:

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="xcopy &quot;$(SolutionDir)\Ethereum.Contracts\bin\$(ConfigurationName)\*.abi&quot; &quot;$(TargetDir)&quot; /Y /I&#xA;&#xA;&#xD;&#xA;xcopy &quot;$(SolutionDir)\Ethereum.Contracts\bin\$(ConfigurationName)\*.bin&quot; &quot;$(TargetDir)&quot; /Y /I" />
</Target>

更新(关于AddPayloadsFolder目标):

AddPayloadsFolder目标定义为

<Target Name="AddPayloadsFolder" AfterTargets="AfterPublish">

未执行,因为AfterTargets dotnet publish的正确值为Publish,而非AfterPublish。我没有找到关于这个事实的明确文档,但在this issue中提到了它。

还要考虑使用多个命令替换换行符分隔符分隔的多个xcopy命令。当我最终执行AddPayloadsFolder目标时,我收到了由\r分隔符附加到命令行引起的错误。

总结以上所有内容,此处已调整PostBuildAddPayloadsFolder目标:

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="xcopy &quot;$(SolutionDir)\Ethereum.Contracts\bin\$(ConfigurationName)\*.abi&quot; &quot;$(TargetDir)&quot; /Y /I" />
    <Exec Command="xcopy &quot;$(SolutionDir)\Ethereum.Contracts\bin\$(ConfigurationName)\*.bin&quot; &quot;$(TargetDir)&quot; /Y /I" />
</Target>

<Target Name="AddPayloadsFolder" AfterTargets="Publish">
    <Exec Command="xcopy &quot;$(TargetDir)*.abi&quot; &quot;$(PublishDir)&quot; /Y /I" />
    <Exec Command="xcopy &quot;$(TargetDir)*.bin&quot; &quot;$(PublishDir)&quot; /Y /I" />
</Target>

答案 1 :(得分:1)

基于没有 gist 建议的 @Jacob,我已经写下了在 SDK 样式的 csproj 文件中执行此操作的推荐方法。

您首先需要设置一个项目组,指定您要复制的文件。然后您可以使用目标来执行实际的复制步骤。这是取自 VS 网站 (link) 的示例:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <ItemGroup>
  <MySourceFiles Include="a.cs;b.cs;c.cs"/>
 </ItemGroup>
 <Target Name="CopyFiles">
  <Copy SourceFiles="@(MySourceFiles)" DestinationFolder="c:\MyProject\Destination" />
 </Target>
</Project>

您还需要指定何时需要调用目标(除非您想显式调用它)。对于普通构建,您通常会在构建 (AfterBuild) 之后调用它。发布项目时,选择 Publish 目标。如果需要两次执行,则调用两次:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <ItemGroup>
  <MySourceFiles Include="a.cs;b.cs;c.cs"/>
 </ItemGroup>
 <Target Name="CopyExtraFiles" AfterTargets="AfterBuild">
  <Copy SourceFiles="@(MySourceFiles)" DestinationFolder="c:\MyProject\Destination" />
 </Target>
 <Target Name="PublishExtraFiles" AfterTargets="Publish">
  <Copy SourceFiles="@(MySourceFiles)" DestinationFolder="c:\MyProject\Destination" />
 </Target>
</Project>

有关 Copy task 的更多信息,请参阅文档。当你需要复制一个完整的目录结构时,你可能需要这个:

<Copy SourceFiles="@(MySourceFiles)"
      DestinationFiles="@(MySourceFiles->'c:\MyDestinationTree\%(RecursiveDir)%(Filename)%(Extension)')" />