Install any skill in seconds. Free to start, no credit card required.
Get Started Free →dotnet/copy-to-output-directory
Choosing an MSBuild CopyToOutputDirectory / CopyToPublishDirectory mode: Never, PreserveNewest, Always, and IfDifferent (MSBuild 17.13+), plus $(SkipUnchangedFilesOnCopyAlways). USE FOR: removing the per-build Always copy perf hit; resetting output files mutated between builds. DO NOT USE FOR: general incremental-build diagnosis (use incremental-build); non-MSBuild build systems.
Passed 23 of 23 test cases with the skill, and 14 of 23 without it.
and 8 more in the full report
9 fixed14 passed either way0 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 9 test cases the skill fixed. Same model, same prompt, with and without the skill.
Which internal MSBuild parent target orchestrates the execution of the individual copy targets (`_CopyOutOfDateSourceItemsToOutputDirectory`, `_CopyOutOfDateSourceItemsToOutputDirectoryAlways`, and `_CopyDifferingSourceItemsToOutputDirectory`) during a build?
| Checked | Without skill | With skill |
|---|---|---|
| Identifies _CopySourceItemsToOutputDirectory as the parent target. | Missed | Passed |
The instructions your model reads when the skill loads.
The CopyToOutputDirectory metadata (and its publish counterpart CopyToPublishDirectory) controls whether an item — Content, None, EmbeddedResource, or Compile — is copied next to your build output, and under what conditions the copy happens. Picking the wrong mode causes either stale files in bin/ or an unnecessary per-build performance hit.
As of MSBuild 17.13 / .NET SDK 9.0.2xx there are four values:
| Mode | Copies when… | Incremental cost | Typical use |
|---|---|---|---|
Never (default) | Never | None | Files not needed at runtime |
PreserveNewest | Source is newer than destination (or destination missing) | Cheap (timestamp check) | The common case — source files you edit |
Always | Every build, unconditionally | Expensive — copies on every build even in no-op builds | Legacy workaround; avoid (see below) |
IfDifferent | Source differs from destination in either direction (newer or older, or size differs, or destination missing) | Cheap (timestamp + size check) | Destination may be mutated between builds |
<ItemGroup>
<None Include="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
<None Include="testdata\seed.db" CopyToOutputDirectory="IfDifferent" />
</ItemGroup>
You can use either the attribute form shown above or the child-element form:
<None Include="testdata\seed.db">
<CopyToOutputDirectory>IfDifferent</CopyToOutputDirectory>
</None>
Always is usually the wrong choiceAlways re-copies the file on every build, including otherwise-clean incremental/no-op builds. On projects with many or large content files this is a measurable, recurring cost and a common cause of "why is my no-op build not instant?" reports.
Historically Always was the only way to handle a specific scenario: the destination file can change between builds — for example an SQLite database, a storage/state file, or a config file that a test run mutates. With PreserveNewest, if the destination is modified (making its timestamp newer than the source) MSBuild will not restore the original source file, because the source is no longer newer. People reached for Always to force the file back into a known-good state — paying the copy cost on every build as a side effect.
IfDifferent: copy when different, in either directionIfDifferent is the targeted fix for that scenario. It copies the source over the destination whenever MSBuild considers the two different — whether the source is newer or older than the destination, whether the size differs, or the destination is missing — and skips the copy when the destination is unchanged per MSBuild's heuristic.
test cases passed, vs 14 / 23 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.