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
A work colleague has come up with a solution.
He has suggested hand editing the project to remove the DefaultTargets
from the Project (and delete a load of now unused properties).
MSBuild complains if there are no targets in the project so he has added three empty targets.
The final project looks something like this
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{541463A7-7CFA-4F62-B839-6367178B16BD}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
... files ...
</ItemGroup>
<ItemGroup>
... files ...
</ItemGroup>
<Target Name="Build"/>
<Target Name="Rebuild"/>
<Target Name="Clean"/>
</Project>
Admittedly, this solution requires more fiddling that I would have liked but seems to achieve what I was after: namely a project that does not aattempt to produce any build output.
Visual Studio 2015 has a project type called "Shared Project" which is essentially a content only project with no targets. It's listed under Visual C# but it can be used for any files.
Andy posted a link with a solution that's mostly worked for me; basically delete the following line from the project file:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
and add the following lines:
<Target Name="Build">
<Copy
SourceFiles="@(Content)"
DestinationFiles="@(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')" />
</Target>
<Target Name="Clean">
<Exec Command="rd /s /q $(OutputPath)" Condition="Exists($(OutputPath))" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build">
</Target>
I also found that disabling the project Debug property "Enable the Visual Studio hosting process" (for each configuration) prevented the MyProject.vshost.exe file from being generated.
As David I. McIntosh pointed out in a comment on this answer, if your project is part of a solution with multiple projects and any other projects use the same output path as the content-only project, the above Clean
target will delete all of the files in the output path, i.e. the build output of other projects, and would thus only be correct if the content-only project is the first project built (among those sharing the same build output path). The following is a safer and friendlier Clean
target for this scenario:
<Target Name="Clean">
<Delete Files="@(Content->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')"/>
</Target>
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:
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).
Then, try creating a Blank solution
. Create Empty project
. Have your files in respective folders with in the solution folder. From property window, use the Show all files
, include those folders into the project. There is no better solution other then this. I hope.
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)%(Extension)')"/>
</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.