21

I have a solution with two executable projects.

Main.exe is dependent on Subordinate.exe.

These projects both have App.config files, so in their respective output directories, I have Main.exe.config and Subordinate.exe.config.

When I build Main.exe, Subordinate.exe is copied into Main's output directory, but Subordinate.exe.config is not.

Is there a standard way to tell Visual Studio to do this?

Mud
  • 28,277
  • 11
  • 59
  • 92
  • 2
    An alternative approach is to edit the csproj file for the parent project and use the AllowedReferenceRelatedFileExtensions in a propertygroup. In your case you would add .exe.config to the list of allowed extensions. See: https://stackoverflow.com/questions/9765686/include-referenced-projects-config-file/9769667#9769667 – Daniel Lee Jan 20 '15 at 17:09

3 Answers3

14

Another way I found is by adding the app.config file as a linked file to the dependent project, e.g. here you would add a link to Subordinate.exe's app.config into Main.exe's project, and set it to be copied to the output directory when built. You can then change the name of the file that is copied to Main.exe's output directory at build time by editing the <Link> element in your project file, something like:

<None Include="..\Subordinate.ProjectFolder\app.config">
  <Link>Subordinate.exe.config</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

This has the same issue that you have to hardcode the name of the generated config file, but that's no worse than the AfterBuild approach, and I find this method a little more transparent, and it removes the build-order dependency issue that you mentioned.

adrian
  • 2,793
  • 1
  • 23
  • 26
11

Right click on the Main project and select Edit Project File. Add an AfterBuild event:

  <Target Name="AfterBuild">
    <Copy SourceFiles="..\Subordinate\bin\$(Configuration)\Subordinate.exe.config" 
          DestinationFolder="$(TargetDir)" />
  </Target>
KMoraz
  • 14,004
  • 3
  • 49
  • 82
  • I had already tried this, using `PostBuildEvent`, and found that it was failing on first attempt to build, then succeeding on the second attempt. Turns out in my *real* project the subordinate project was not listed as a dependency of the main project, so it was built after the main project. Once I established the dependency correctly, the post build event worked. **--** Anyway, I was hoping for a answer that didn't require a AfterBuild/PostBuildEvent, but given that none is forthcoming, I'm marking this as the answer (since it's what I did). – Mud Jan 17 '12 at 19:50
  • 1
    I'd avoid `PostBuildEvent` at all costs. `AfterBuild` is preferable as it at least build-controlled and traceable. – KMoraz Jan 17 '12 at 22:15
  • I'd just like to add that in VS2012, the macro for configuration (e.g. Debug/Release) is $(ConfigurationName), not $(Configuration). Also, you may need to include a platform specification (e.g. x86/x64). You may end up needing to write it like: – Aaron Hudon Mar 12 '15 at 17:52
  • It is kinda kludge, isn't it – Alexey Kozhanov Dec 29 '16 at 10:36
1

Have a look at this answer (based on work of @theyetiman). It requires mainly a modification of the project, the app.config file belongs to. The consuming projects are left unmodified.

<ItemGroup>
  <None Include="app.config" />
</ItemGroup>
<ItemGroup>
  <None Include="app.config">
    <Link>$(TargetFileName).config</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

Also note, that with Visual Studio 2017 this modification is not necessary any more. If you open a solution with a project containing the above workaround, a warning similar to the following is displayed in the errors window:

The file 'app.config' could not be added to the project. Cannot add a link to the file ...\app.config. This file is within the project directory tree.

Add a condition comparing $(VisualStudioVersion) to avoid this warning and keep backward compatibility:

<ItemGroup>
  <None Include="app.config" />
</ItemGroup>
<ItemGroup Condition="'$(VisualStudioVersion)' &lt; '15.0'">
  <None Include="app.config">
    <Link>$(TargetFileName).config</Link>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>
CodeFox
  • 3,321
  • 1
  • 29
  • 41