dotnet publish 包括额外的文件
dotnet publish include extra files
我有一个 netcore 应用程序取决于我的自定义项目。因为我不能直接引用它,所以我写了将我的文件复制到输出的postbuildevents:
xcopy "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I
xcopy "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I
当我构建和 运行 项目时它工作正常,但是当 运行 publish
命令时它不包含这些文件。
怎么做到的?我也试过 但 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 "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I


xcopy "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I" />
</Target>
<Target Name="AddPayloadsFolder" AfterTargets="AfterPublish">
<Exec Command="xcopy "$(TargetDir)\*.abi" "$(PublishDir)" /Y /I


xcopy "$(TargetDir)\*.bin" "$(PublishDir)" /Y /I" />
</Target>
</Project>
当您启动 dotnet publish
命令时,未定义 $(SolutionDir)
宏。结果 xcopy
使用不正确的源路径启动。
缺少解决方案宏的问题是 described here,它仍处于打开状态。我不确定它是否会被修复,因为 $(SolutionDir)
是 IDE-specific 宏。
要解决您的问题,您可以通过开关 /p
:
将 $(SolutionDir)
宏的值传递给 dotnet publish
命令
dotnet publish -c Release -r win-x64
/p:SolutionDir="D:\projects\SolutionDir"
您还应该在 $(SolutionDir)
宏之后添加一个反斜杠:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I


xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I" />
</Target>
更新(关于AddPayloadsFolder
目标):
AddPayloadsFolder
目标定义为
<Target Name="AddPayloadsFolder" AfterTargets="AfterPublish">
未执行,因为 dotnet publish
的 AfterTargets
的正确值是 Publish
,而不是 AfterPublish
。我没有找到关于这个事实的明确文档,但是在 this issue.
中提到了它
同时考虑用多个命令替换由换行符分隔的几个 xcopy
命令。当我最终执行 AddPayloadsFolder
目标时,我收到了由附加到命令行的 \r
定界符引起的错误。
总结以上所有内容,这里调整了 PostBuild
和 AddPayloadsFolder
目标:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I" />
<Exec Command="xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I" />
</Target>
<Target Name="AddPayloadsFolder" AfterTargets="Publish">
<Exec Command="xcopy "$(TargetDir)*.abi" "$(PublishDir)" /Y /I" />
<Exec Command="xcopy "$(TargetDir)*.bin" "$(PublishDir)" /Y /I" />
</Target>
根据 gist that @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
)。发布项目时,select 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)')" />
关于 SolutionDir 的评论不可用 - 不是作为对问题本身的回答,而是作为需要考虑的事情。
如果您在名为“Directory.Build.props”的解决方案目录中创建一个包含以下内容的文件,那么它会为您定义 SolutionDir 变量:
<Project>
<PropertyGroup>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
</PropertyGroup>
</Project>
我有一个 netcore 应用程序取决于我的自定义项目。因为我不能直接引用它,所以我写了将我的文件复制到输出的postbuildevents:
xcopy "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I
xcopy "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I
当我构建和 运行 项目时它工作正常,但是当 运行 publish
命令时它不包含这些文件。
怎么做到的?我也试过 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 "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I


xcopy "$(SolutionDir)Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I" />
</Target>
<Target Name="AddPayloadsFolder" AfterTargets="AfterPublish">
<Exec Command="xcopy "$(TargetDir)\*.abi" "$(PublishDir)" /Y /I


xcopy "$(TargetDir)\*.bin" "$(PublishDir)" /Y /I" />
</Target>
</Project>
当您启动 dotnet publish
命令时,未定义 $(SolutionDir)
宏。结果 xcopy
使用不正确的源路径启动。
缺少解决方案宏的问题是 described here,它仍处于打开状态。我不确定它是否会被修复,因为 $(SolutionDir)
是 IDE-specific 宏。
要解决您的问题,您可以通过开关 /p
:
$(SolutionDir)
宏的值传递给 dotnet publish
命令
dotnet publish -c Release -r win-x64 /p:SolutionDir="D:\projects\SolutionDir"
您还应该在 $(SolutionDir)
宏之后添加一个反斜杠:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I


xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I" />
</Target>
更新(关于AddPayloadsFolder
目标):
AddPayloadsFolder
目标定义为
<Target Name="AddPayloadsFolder" AfterTargets="AfterPublish">
未执行,因为 dotnet publish
的 AfterTargets
的正确值是 Publish
,而不是 AfterPublish
。我没有找到关于这个事实的明确文档,但是在 this issue.
同时考虑用多个命令替换由换行符分隔的几个 xcopy
命令。当我最终执行 AddPayloadsFolder
目标时,我收到了由附加到命令行的 \r
定界符引起的错误。
总结以上所有内容,这里调整了 PostBuild
和 AddPayloadsFolder
目标:
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.abi" "$(TargetDir)" /Y /I" />
<Exec Command="xcopy "$(SolutionDir)\Ethereum.Contracts\bin$(ConfigurationName)\*.bin" "$(TargetDir)" /Y /I" />
</Target>
<Target Name="AddPayloadsFolder" AfterTargets="Publish">
<Exec Command="xcopy "$(TargetDir)*.abi" "$(PublishDir)" /Y /I" />
<Exec Command="xcopy "$(TargetDir)*.bin" "$(PublishDir)" /Y /I" />
</Target>
根据 gist that @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
)。发布项目时,select 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)')" />
关于 SolutionDir 的评论不可用 - 不是作为对问题本身的回答,而是作为需要考虑的事情。
如果您在名为“Directory.Build.props”的解决方案目录中创建一个包含以下内容的文件,那么它会为您定义 SolutionDir 变量:
<Project>
<PropertyGroup>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
</PropertyGroup>
</Project>