Is there such a thing as a "content/data only project" in visual studio

Viewed 6337

I have a bunch of ancillary XML and XSLT files that I want to edit and manage in visual studio.

The files do not logically belong under any code project in my solution and so in order to group them neatly, I have created a "dummy" C# dll project in visual studio and disabled it from building in Debug / release builds).

I wondered if there was a nicer way of achieving the same result (i.e. having all the files visible in solution explorer). What I think really want is a visual studio project type of "content only" but such a thing does not exist (or have I not looked hard enough?).

I have toyed with the idea of adding the files as solution items but then they seem harder to manage because creating a new "solution item folder" does not actually create a folder on disk.

Any one have any ideas?

6 Answers

This answer is just a convenient consolidation of the answers above given by Chris Fewtrell and Kenny Evitt, along with the slight modification in my comments above, and a bit more detail on what the declaration of the content items should/could look like:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProjectGuid>{541463A7-7CFA-4F62-B839-6367178B16BD}</ProjectGuid>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Configuration)|$(Platform)' == '64-bit|AnyCPU'">
        <PlatformTarget>x64</PlatformTarget>
        <OutputPath>..\builds\$(Configuration)\</OutputPath>
        <IntermediateOutputPath>..\builds\$(Configuration)\Intermediate\YourProjectName\</IntermediateOutputPath>
    </PropertyGroup>
    <ItemGroup>
        <Content Include="fileInProjectFolder.csv" />
        <Content Include="SubDir\fileInSubdir.txt" />
        <Content Include="..\actualSourceDirectoryOfFile\app.log.basic.config">
          <Link>targetSubdirInOutputDir\app.log.basic.config</Link>
        </Content>
        <Content Include="..\actualSourceDirectoryOfFile\yetAnotherFile.config">
          <Link>yetAnotherFile.config</Link>
        </Content>
        ... more files ...
    </ItemGroup>
    <Target Name="Build">
        <Copy
            SourceFiles="@(Content)"
            DestinationFiles="@(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')" />
    </Target>
    <Target Name="Clean">
        <Delete Files="@(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(E‌​xtension)')"/>
    </Target>
    <Target Name="Rebuild" DependsOnTargets="Clean;Build">
    </Target>
</Project>

Note that this always copies all the "content" files to the output directory - the options "Copy If Newer", "Copy Always" and "Do Not Copy", as presented in the visual studio GUI ( appears as, for example, <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> in the .csproj file) are ignored.

In my situation, I needed to have a set of configuration files that would be common to many projects. To simply achieve this, I performed the following steps:

  1. Create a Class Library project named "Configuration"
  2. Delete all *.cs files from Configuration project
  3. Put configuration files in a "Configuration" folder in the Configuration project
  4. Copy configuration files to required projects in the post-build event. In Configuration project's Properties > Build Events > Post-build event:
xcopy "$(TargetDir)Configuration\*" "$(SolutionDir)TARGET_PROJECT\$(OutDir)" /i /v /q /s /y

In the above, replace TARGET_PROJECT with your actual project

This will copy all the files in the Configurations folder to the output directory of the project that needs the configuration files (eg. MyProject/bin/Debug, etc).

Related