Reputation: 3299
I'm able to have files put into the bin directory using the properties "copy if newer".
The problem I have is that I require a large number of dll files to be put along side my application. This means that my project becomes littered with a large number of files.
I'd like to put my files into an assets folder in my solution but have the files present in the bin directory on build. I have tried using post build events but I keep getting windows error codes (even when it's successful).
Is there an alternative way to have the external dlls accessible to my application?
Upvotes: 3
Views: 2265
Reputation: 42434
If you unload the project file you can edit the .csproj file.
Near the end you'll find:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
-->
Lets modify that.
First define which Items the AfterBuild task is going to copy. Notice that you only have to make sure these files exist on your disk in a folder (you say it is called assets) and are under source control. You don't need to include any of those files in your solution or project.
<ItemGroup>
<!-- Include relative to this project file, so ..\assets would bring you to the solution folder
Take all files in the assets folder and subfolders, except *.txt files
-->
<Asset Include="assets\**" Exclude="*.txt">
</Asset>
<!-- take all *.txt files -->
<TextAsset Include="assets\**\*.txt">
<!-- meta data -->
<SubPath>TextFiles</SubPath>
</TextAsset>
</ItemGroup>
Now you'll have two Item collection, one called Asset and one called TextAsset. Those items can be consumed in build Tasks. We are going to use the Copy task. I've commented the build script to explain what happens.
<!-- this does what the name suggests-->
<Target Name="AfterBuild">
<!-- log -->
<Message Importance="high" Text="Start Copying assets"/>
<!-- copy Asset files to one folder (flattens) -->
<Copy SourceFiles="@(Asset)"
DestinationFolder="$(OutputPath)" />
<!-- copy TextAsset files to a subpath, keep folder structure-->
<Copy SourceFiles="@(TextAsset)"
DestinationFiles="@(TextAsset->'$(OutputPath)%(SubPath)\%(RecursiveDir)%(Filename)%(Extension)')" />
<!-- done logging -->
<Message Importance="high" Text="Copied assets"/>
</Target>
Notice that I used the property $(OutputPath)
which is one of the well known properties. A similar list exists for item meta data.
The changes will not affect the operation of visual studio. Your changes will be preserved when adding or removing regular project items and/or project settings. As you'll keep this file in source control, also on your buildserver the same targets will be run, doing the same copy.
I prefer to test these build targets from the commandline, specifying only the target I'm interested in, like so:
msbuild Application2.csproj /t:AfterBuild
That gives you a much quicker round-trip time instead of doing a full build.
Upvotes: 2