Click here to Skip to main content
15,884,298 members
Articles / Programming Languages / C#
Tip/Trick

Centralized place for documents and templates - VS Build Task

Rate me:
Please Sign up or sign in to vote.
3.00/5 (1 vote)
27 Jun 2014CPOL3 min read 7.7K   22   6   2
How to copy files to central place set in configuration or setup directly with visual studio build task

Introduction

This is used for copying all files from source directory to destination directory using Build Task. Here it accepts configuration file and reads only destination Key in Application Settings.

Background

You should start with these posts, this should explain more principles for Microsoft.Build.Utilities.Task.

http://msdn.microsoft.com/en-us/library/ms366724.aspx

http://bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx

Why use central place for templates

To have templates (XSLT, doc, etc.) for generating document in one place is good for editing when you have a lot of different components (services and applications) that uses templates. You do not need to search through servers and folders to find where templates are for simple small changes. If it is on central place you always now where to start.

If it is required to be shared across the network, again you have only one place to allow users to access templates. You will not have to adding several network sharing privileges.

Cons: this centralizing place for templates in one folder is setting build and deploys process for copy these templates to one place. In this article I will try to explain it as best I can.

How to

To set up and use this Copy Files build task you need to set in project dir:
1. Open the *.proj file.

2. Add a UsingTask element to the file and specify the details of your task. For example:

C#
<UsingTask TaskName="FileCopyTask" AssemblyFile="$(ProjectDir)..\Assemblies\drej.CopyFiles.dll"  />

3. Save the file.

4. Uncomment <Target Name="AfterBuild"></Target>

5. Add the task element to run your task inside the Target element. For example:

C#
<Target Name="AfterBuild">
    <FileCopyTask />
</Target>

6. Then setup parameters of task. It is requred to have source with destination, or source with configuration file and Config key. 
Configuration Key is read from AppSettings section in config file. For Example:

C#
<FileCopyTask SourceDirectory="$(ProjectDir)..\Templates" ConfigurationFilePath="$(ProjectDir)\App.config" ConfigurationKey="TemplateFolder" />

or

C#
<FileCopyTask SourceDirectory="$(ProjectDir)..\Templates" DestinationDirectory="c:\DocFolder\Templates" />

7. There is one optional parameter OnlyFileTypes where can you set search pattern like this:

C#
<FileCopyTask SourceDirectory="$(ProjectDir)..\Templates" DestinationDirectory="c:\DocFolder\Templates" OnlyFileTypes="*.xml" />

On search pattern you can find more info here: http://msdn.microsoft.com/en-us/library/wz42302f.aspx

How it is done in C#

There are two parts of solution in coping files:

1. Setup of all parameters - source directory, target directory and file types to copy

2. Coping files from source to target destination

Setup of all parameters

Source directory is set up to folder in project to relative destination. This parameter is set to required.

C#
Required]
public string SourceDirectory { get; set; }

If destination directory is set then nothing more is required to be set up. It is just read from project file.

Other method is when Source directory is setup and also config file and then key. Here is the key that you can use environment (Dev, Testing, Release, etc.) to change value of config key and to use it during build. Here is the code for reading key from configuration file.

C#
this.Source = SourceDirectory;
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap() { ExeConfigFilename = ConfigurationFilePath };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
if (config.AppSettings.Settings != null
    && config.AppSettings.Settings.Count > 0
    && config.AppSettings.Settings[ConfigurationKey] != null
    && !string.IsNullOrEmpty(config.AppSettings.Settings[ConfigurationKey].Value))
{
    this.Destination = config.AppSettings.Settings[ConfigurationKey].Value;
}

Coping files

Coping files after source and destination is setup is very easy. Just read all the files of the specific type (default search pattern is *.*) and copy it to destination:

C#
FileInfo[] filesToCopy = null;
if (string.IsNullOrEmpty(OnlyFileTypes))
    filesToCopy = sourceDir.GetFiles("*.*", SearchOption.AllDirectories);
else
    filesToCopy = sourceDir.GetFiles(OnlyFileTypes, SearchOption.AllDirectories);

if (filesToCopy != null && filesToCopy.Count() > 0)
{
    string pathToCopy = string.Empty;
    foreach (var file in filesToCopy)
    {
        //Creating destination directory if not exists
        pathToCopy = file.DirectoryName.Replace(sourceDir.FullName, destinationDir.FullName);
        if (!Directory.Exists(pathToCopy))
            Directory.CreateDirectory(pathToCopy);

        pathToCopy = Path.Combine(pathToCopy, file.Name);

        try
        {
            Log.LogMessage(MessageImportance.High, "Copying file\nfrom: {0}\nto: {1}\n********", file.FullName, pathToCopy);
            file.CopyTo(pathToCopy, true);
        }
        catch (Exception ex)
        {
            Log.LogErrorFromException(ex);
        }
    }
}

Summary

Why I used Microsoft.Build.Utilities.Task instead of Console App and Post Build Events!? Only one reason is that I am able to fail build from Build Task. It is easier to show info and errors with Microsoft.Build.Utilities Libraries.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
Serbia Serbia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 3 Pin
Cindy Meister30-Jun-14 7:08
Cindy Meister30-Jun-14 7:08 
GeneralRe: My vote of 3 Pin
Andrej Kamikovski10-Jul-14 1:00
Andrej Kamikovski10-Jul-14 1:00 
Thanks for comment.
Cindy Meister wrote:
should still at least mention WHERE the code he provides should go

This is why I provided complete zipped code, and extracted just specific code.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.