この場合、app.configの名前を更新しているのはVisual Studioではなく、VisualStudioから独立したコアMSBuildルールです。app.configモデルをエミュレートする場合は、これが採用する必要のあるアプローチです。
app.configのコピーを制御するビルドシーケンスの2つの部分は、Microsoft.Common.targetsにあります。
最初にファイルの名前が計算されます
<ItemGroup>
<AppConfigWithTargetPath Include="$(AppConfig)" Condition="'$(AppConfig)'!=''">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
次に、ビルドの一部として実際にコピーされます
<Target
Name="_CopyAppConfigFile"
Condition=" '@(AppConfigWithTargetPath)' != '' "
Inputs="@(AppConfigWithTargetPath)"
Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
<!--
Copy the application's .config file, if any.
Not using SkipUnchangedFiles="true" because the application may want to change
the app.config and not have an incremental build replace it.
-->
<Copy
SourceFiles="@(AppConfigWithTargetPath)"
DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')"
OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
Retries="$(CopyRetryCount)"
RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
UseHardlinksIfPossible="$(CreateHardLinksForAdditionalFilesIfPossible)"
>
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
</Target>