-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow CopyToOutputDirectory to have a custom destination path #2795
Comments
This currently works by using the <ItemGroup>
<None Include="../folder1/**/*" Link="folder2\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup> SDK-based projects (default for .NET Core and .NET Standard) now support
I patched up the code from the SDK (minus a fix when referencing shared projects added later on) to be usable in classic projects in https://stackoverflow.com/questions/44423582/link-additional-files-in-visual-studio/44427519#44427519 The downside of using the Personally, I'm fine with the way Example showing usage of both ways: |
Thanks @dasMulli , |
The link element behaves strangely for me in a .net 4.6.2 project. I have a few files in a "wwwroot/build" folder that, when the project builds, i want to output to the /bin/Release/wwwroot folder. In my .csproj file i added the following:
However, after the build, the bin/Release/wwwroot folder contains a few files, but not all of them and some of them even files that do not exist in the wwwroot/build folder (but that do exist in the original wwwroot folder). The msbuild output seems to indicate that a bunch of files are mapped onto a single file with the link element:
The files listed each time above the "CopyToOutputDirectory" are correct. The files that Link=... indicates obviously are not. However, wwwroot\app.config and wwwroot.env are actual files i have present in my project, but i dont want to copy those to my output, just the contents of the build folder (which need to be put in the root of the wwwroot folder in /bin/Release since the build folder contains the actual files that need to be published). |
it's weird, as if the %(Filename)%(Extension) is only being evaluated only once and then being used for every item matching the include. |
For what it's worth, if I placed the
|
I apologize for nudging such an old issue, but I thought I'd try my question here as opposed to opening another new issue. In a .NET Core format With <ItemGroup>
<None Include="TestInput/*" CopyToOutputDirectory="PreserveNewest" Link="LegacyLogsTesterInput/%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup> With <ItemGroup>
<None Include="TestInput/*" CopyToOutputDirectory="PreserveNewest" LinkBase="LegacyLogsTesterInput" />
</ItemGroup> In the former case, I observe that the directory
Does this mean that I cannot use For context, I'm trying to "upgrade" my copy logic from the below XML code to use <Target Name="PostBuild" BeforeTargets="PostBuildEvent">
<Exec Command="xcopy /s /d /y "$(ProjectDir)TestInput\*" "$(OutDir)LegacyLogsTesterInput\"" />
</Target> I'm using Visual Studio 2019 (latest updates as of this post). |
The |
Why not allow user edit in UI? |
@Jaans Your method sadly doesn't seem to work transitively across project references. |
Fixes #2795 and indirectly fixes https://developercommunity.visualstudio.com/t/copytooutputdirectorypreservenewest-ignored-inside/1332219?from=email&viewtype=all#T-ND1363347 Context There's currently no way to include items in a project such that: Visual studio sees them in a specific folder (via <Link>). They are published to a user-defined path (currently controlled via <Link>) Changes Made Modify the AssignTargetPath task to return early if TargetPath metadata is already set on a particular item. Testing Need to add one test covering this. Tested locally with bootstrapped MSBuild on command line Tested locally with a boostrapped msbuild on internal VS Here's the repro I'm using: <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <Content Include="Files\**"> <Link>Files\%(Filename)%(Extension)</Link> <TargetPath>%(Filename)%(Extension)</TargetPath> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> </Project> Notes The other way of solving this problem has to do with Microsoft.Common.CurrentVersion.targets. We modify it so that the AssignTargetPath task look something like this: <AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)" Condition="'%(Content.TargetPath)'==''"> <Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath" /> </AssignTargetPath> <ItemGroup> <ContentWithTargetPath Include="@(Content)" Condition="'%(Content.TargetPath)'!=''"/> </ItemGroup> This seems less efficient to me. AssignTargetPath is also called for all None, Content, and EmbeddedResource files. So if we go this batching route and want None or EmbeddedResource to have this feature, we'd need to batch those as well.
I think link support support single file |
The destination of
CopyToOutputDirectory
attribute in msbuild is fixed, there are various questions about how to change the destination path:https://stackoverflow.com/questions/10204370/can-i-specify-the-output-path-for-the-msbuild-content-tag
https://stackoverflow.com/questions/18591107/copytooutputdirectory-override-destination-path
https://stackoverflow.com/questions/5915610/msbuild-project-file-copy-item-to-specific-location-in-output-directory
https://stackoverflow.com/questions/1014207/copy-to-output-directory-copies-folder-structure-but-only-want-to-copy-files/21534669#21534669
The simplest accepted answer requires a custom msbuild task or command running after the build. Please add an additional
OutputDirectory
attribute.Project file
Directory contents:
Command line
Expected behavior
Output directory contents:
Actual behavior
Output directory contents:
The text was updated successfully, but these errors were encountered: