Click here to Skip to main content
Click here to Skip to main content

Custom MSBuild Tasks: Automated Report and DB Deployment

, 22 Jun 2006
Rate this:
Please Sign up or sign in to vote.
Automate your Reporting Services report deployment and scripting and database tasks by using these custom MSBuild tasks.

Sample Image - CustomMSBuildTask_RS.jpg

Introduction

This library wraps the RS.exe tool and the OSQL.exe tool in custom MSBuild tasks, so you can automate Reporting Services Report and Scripting deployment, and SQL Server object scripting into an MSBuild project. The Osql custom task is based on the sample by Joey Benninghove, found on his blog.

You can create custom tasks for MSBuild by extending/deriving from the Task base class or by implementing the ITask interface. Feel free to use the source code, and please send me any comments or improvements.

Usage

To consume one of these tasks, just create an XML-based MSBuild project file like the following, and run it using the MSBuild.exe command:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="DeployReportCatalog" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask AssemblyFile=
  "C:\Projects\Silvaware.MSBuild.Tasks\bin\Debug\Silvaware.MSBuild.Tasks.dll" 
  TaskName="Rs" />

 <PropertyGroup>
    <SqlToolsFolder>C:\program files\microsoft sql server\90\Tools\Binn
    </SqlToolsFolder>  
    <RsTool>$(SqlToolsFolder)\rs.exe</RsTool>
    <TargetReportServer>http://localhost/ReportServer</TargetReportServer>
</PropertyGroup>

 <ItemGroup>
     <TargetItems Include="**\*.rss" />
 </ItemGroup>

 <Target Name="DeployReportCatalog">   
     <Rs RsPath="$(RsTool)" InputFile="@(TargetItems)" 
         ServerURL="$(TargetReportServer)" WaitForExit="true" />
 </Target>

</Project>

The example above executes all Reporting Services script files (.rss) found in the subdirectories of this project recursively. These .rss files could contain VB.NET code to deploy report RDLs, datasources, create folders, roles, assign security, etc.

All the arguments/parameters that the RS.exe and the OSQL.exe tool can take from the command line have been exposed in the custom task as public properties, such as the RsPath and the InputFile properties used in the above example.

Happy MSBuild-ing!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Thiago Silva
Architect Credera
United States United States
Thiago started programming on Turbo Pascal at age 17, and quickly moved on to java and VB6, and finally landing on .NET. He has implemented custom .NET applications and BI Reporting solutions for many clients.
 
Thiago has co-authored a couple of SQL Server Reporting Services books, and also dabbles in SharePoint and many things Microsoft.
 
He is currently an architect/consultant for a specialized consulting firm in the Dallas area.
Follow on   Twitter

Comments and Discussions

 
GeneralA couple of minor modifications Pinmemberdeiussum16-Jun-09 10:46 
Thanks for the great MSBuild task Thiago!
 
I needed a couple of slight modifications to your existing code and thought I would share them here.
 
For the variables, I needed the ability to pass multiple variables to my script. I didn't see a way to do that with your current code so I modified it slightly to take in a comma or semi-colon delimited list of variables. I changed part of Rs.GetRsArguments to look like this for the _variables check:
 
    if (!string.IsNullOrEmpty(_variables))
    {
        string[] vars = _variables.Split(';', ',');
	foreach (string var in vars)
	{
            rsArguments.AppendFormat("-v \"{0}\" ", var);
	}
    }
 
I also need to be able to see if there were errors in the RSS scripts, so I hooked up the StdError and StdOutput redirection. In Rs.RunRsCommand I added the following.
 
	proc.StartInfo.RedirectStandardError = true;
	proc.StartInfo.RedirectStandardOutput = true;
	proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
	proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
 

        string execPrompt = rm.GetString("Exec", CultureInfo.CurrentUICulture);
        Log.LogMessage(execPrompt + proc.StartInfo.FileName + " " + proc.StartInfo.Arguments);
 
        try
        {
            proc.Start();
            proc.BeginOutputReadLine();
            proc.BeginErrorReadLine();
            if (_waitForExit)
            {
                proc.WaitForExit();							     }
            }            
        }
 
And the new functions to handle the events look like so:
	void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
	{
		if (e.Data != null)
		{
			Log.LogMessage(e.Data);
		}
	}
 
	void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
	{
		if (e.Data != null)
		{
			Log.LogError(e.Data);
		}
	}

General[Message Removed] Pinmemberstonber6-Oct-08 8:37 
GeneralContribute ti tigris Pinmemberwinstanley-john2-Oct-07 8:00 
GeneralQuestion. PinmemberRZOE16-May-07 13:10 
GeneralRe: Question. PinmemberThiago Silva12-Jun-07 9:20 
GeneralRe: Question. PinmemberMember 255612624-Mar-08 3:54 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 22 Jun 2006
Article Copyright 2006 by Thiago Silva
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid