.net.net-core.net-core-2.0

dotnet publish include extra files


I have a netcore application depends on my custom project. Because I cannot reference it directly, I have written postbuildevents that are copying my files to output:

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

It works fine when I build and run project, but when run publish command it doesn't include these files.

How can it be done? I tried this approach as well but AddPayloadsFolder doesn't get called.

My 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>

Solution

  • When you launch dotnet publish command, $(SolutionDir) macros is not defined. As result xcopy is launched with incorrect source path.

    The issue with missing solution macros is described here and it's still in opened state. I'm not sure it will be ever fixed because $(SolutionDir) is IDE-specific macros.

    To fix your problem, you could pass the value for $(SolutionDir) macros to dotnet publish command via switch /p:

    dotnet publish -c Release -r win-x64 /p:SolutionDir="D:\projects\SolutionDir"

    You should also add a backslash after $(SolutionDir) macros:

    <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>
    

    UPDATE (regarding AddPayloadsFolder target):

    AddPayloadsFolder target defined as

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

    is not executed since the correct value of AfterTargets for dotnet publish is Publish, not AfterPublish. I have not found explicit documentation for this fact, however it is mentioned in this issue.

    Also consider replacing several xcopy commands delimited by newline separator with multiple commands. When I got AddPayloadsFolder target finally executed, I got an error caused by \r delimiter appended to the command line.

    Summarizing all of the above, here are adjusted PostBuild and AddPayloadsFolder targets:

    <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>