Deploying a SQL Server Reporting Services 2005 report via an MSI


Most of the time, it’s acceptable for customers to deploy a report manually via Visual Studio, Report Manager, or maybe by using an rss script.


 


Last month I bumped into an organization that had a hard and fast rule that “anything deployable” (Winform apps, Webform apps, SSRS reports, etc.) had to be deployed via an MSI.


 


So, I put together a little proof of concept showing them how. The sample basically displays some “setup ui” to collect information like where the data source for the report should be created and what it’s name should be, and the username and password that should be used in the data source. Making all this information “dynamic” was important because one often publishes a report and its data source to a different location on a production box than on the machine it was originally created on…your database server name (and even the name of the database) might be different, too


 


The setup UI runs in the context of a VS deployment package. Once the setup information has been collected, the deployment package launches a custom action. The custom action is nothing more than code which leverages the Reporting Services SOAP APIs to publish the report and data source.


 


After you have downloaded and unzipped the files, open the PublishReportMSI solution, and enjoy this little walkthrough:


 


1.      Open the PublishReportProject project: this sucker is the Setup Project that we use to invoke a Custom Action that does all the real work of publishing a report and fixing up its data source.


2.      Right-click PublishReportProject and choose View | File System. You’ll see a new folder in this list called “TempFolder”, and it contains SampleReport.rdl. SampleReport.Rdl is a report which uses a Data Source called “MyOlap”, and MyOlap hits a cube inside a database named MySSAS. Needless to say, even once you get this thing published on your server, the report itself won’t work since you don’t have my back-end stuff…Sorry!


3.      Choose View | User Interface. Under Start, you’ll see where I added 2 Textbox forms to gather information from the user. If you look at the properties of each form, you’ll see that each Label (Like “Data Source Location”) has an associated Property name(“DSL”) and a Default Value (“/Data Sources”). We’ll use the Property values later on…Also notice how I didn’t hash out the username / password…a bad idea, but I’m in a hurry.


4.      Choose View | Custom Actions, and you’ll see how we launch the Custom Action which does the real work. Note the Install folder and how it contains ClassLibrary1.dll. ClassLibrary1 contains all the SSRS web service API logic that publishes our report and data source. Right-click ClassLibrary1.dll and choose Properties.


5.      Eyeball the CustomActionData property. This is how we “feed” all of the information that we collected in our user interface to the class library. You’ll see the same thing over and over again here: /PropertyName = [PropertyName] , Basically, /PropertyName represents a variable in the class library (which we haven’t looked at yet), and we set this value with = [PropertyName]. [PropertyName] is the value we specified in the Edit?Property property back in the User Interface area.


 


I found this part to be the trickiest thing I had to play around with…just be patient or search MSDN about how CustomActionData works.


 


OK…so you now should see how we:


 


·        Copy a report (in this case SampleReport.rdl) to a temp folder on the machine that the MSI gets run on


·        Collect information from the user about where to publish this report


·        Push the user-provided info to a custom action which lives inside a Class Library


 


Next, let’s look at the Class Library itself. Open The ClassLibrary1 project, double-click Class1.cs and switch to code view.


 


1.      First, check the web references for this project…note anything familiar? We’re just leveraging the 2005 SSRS Management endpoint…no big deal.


2.      OK, check out the code next. I was lazy, so a lot of this stuff could be made more dynamic…I didn’t bother though. In the Install() method, we begin by assigning all those values we collected in the MSI UI to local variables.


3.      Next, we authenticate against the web service and create a folder in SSRS called “MSI Report Demo”. We’ll be dropping our report here later on.


4.      After that, it’s time to read the definition of SampleReport.rdl (which our MSI has already dumped in c:\temp). We plug the definition into an array of bytes called reportDefinition.


5.      Then, we create the report with a call to CreateReport()…again, note the hardcoded values…yuk!


6.      The next thing to do is re-create the data source that the report will depend on. We do so largely using the values we collected from the user earlier on. Calling CreateDataSource() pushes the data source out to the SSRS instance.


Warning: When you play with this, make sure you are regularly cleaning up (deleting) the /MSI Report Demo folder & report, AND the data source from your SSRS instance BEFORE you run the MSI..if you forget, we’ll throw an exception because I didn’t bother to handle scenarios where this stuff already exists on the server…that’s what you get for trying to use free code.


7.      After the data source has been created, we have to circle back to our recently published report and “fix up” its data source reference so the report “knows” where its data source is…Note the hard coded values.


8.      Finally, we make a feeble attempt to clean up by deleting the Sample Report from the file system.


 


I assume you will probably want to get “your” version of the publisher working as quickly as possible…Here’s what you need to do:


 


1.      Replace the strings “SampleReport” or “SampleReport.RDL” with “YourReportName” and “YourReportName.RDL” on lines 44, 47, 88, 91, 97 of Class1.cs and anywhere else you happen to see them show up J


2.      Back in the Deployment Project, delete my SampleReport.rdl as a resource.


3.      Right-click the setup project and select View | System, then Add your RDL doc to the TempFolder (Right-click TempFolder, choose Add).


4.      Rebuild!


5.      You should be ready to install now…This worked for me every time I tried it, but of course your mileage may vary depending on what you try to publish. I suggest you start simple, then get more daring J


 


Also remember that when you run the MSI, you are essentially installing an application. If setup completes with no errors, don’t forget to right-click the setup project in Solution Explorer and choose Uninstall before you try and run the MSI again…

PublishReportWithMSI.zip

Comments (23)

  1. Anonymous says:

    Good Day sir,

    finaly a way to deploy reprots automatically. but before i try this can this be done in SSRS 2000 with SP2 only?

    thanks

    ~jayjay

  2. You will have to modify the sample so that it uses the SSRS 2000 web service endpoint rather than the 2005 endpoint (which is what this samples utilizes)

  3. Anonymous says:

    hi,

    the setup is reading rdl files from a file system. if i want to pull all my rdl files into the temp folder in setup project and read from there itself. how do i do ?

    i hope u understood the question.

    instead of reading from file system , i should read the file from the project itself, that is i will embedded all my reports in the project

  4. Sorry, I can’t help you there…I don’t know enough about setup projects myself.

  5. Anonymous says:

    Hi !

    I want to deploy my reports in the sharepoint website.Could you help me how to do that with the TargetReport folder,Target server url.,

    Thank You

  6. sarathv says:

    In the sample your getting parmeters from custom install of data source and report

    i want to add one more parameter how can i add in the sample code.

    i am passing DirectoryInfo that means file folder information from custom install of data source and report

    thats way i am adding this parameter

    string rfl = this.Context.Parameters["RFL"];

    i created properties for texboxes(A) regarding my new parameter but i didn’t get that parameter how can i create new parameter.

    below is the sample code parameters.

    // get parameters for custom install of data source and report

               string dataSourceName = this.Context.Parameters["DSN"];

               string dataSourceLocation = this.Context.Parameters["DSL"];

               string sqlServerName = this.Context.Parameters["DSSERVERNAME"];

               string dbName = this.Context.Parameters["DBNAME"];

               string uid = this.Context.Parameters["UID"];

               string pwd = this.Context.Parameters["PWD"];

  7. Anonymous says:

    can u tell me how to change the url in app.config??

  8. Anonymous says:

    Hi,

      Nice Article. I have a question here. This MSI deploys reports on the machine where it is running.  But how to deploy reports on remote machine? Will it sipport?

    Thanks

    Anjan

  9. Anonymous says:

    Hi,

    I have tried with the above solution, but how can I add more reports into MSI as I have around 220 reports in my solution.

    Here I can able to add only one reports at a time!

    Please could you help me on this issue.

    RaviPola.

  10. Ravi, you’d just write code which uses the File system object or system.io to loop through every RDL in a temp folder and push it out…

  11. Anonymous says:

    Hi this was a nice article.But when i tried to deploy reports in a remote report server it threw the error ‘Server  Application Error’ .The client received text/html type but expected text/xml. Please help me to solve this error.

  12. Anonymous says:

    Hi,

    I have tried the below link but its asking me for user name and password

    http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&sectionid=4743&postid=1479653

    I want to deploy my reports in the sharepoint website.Could you help me how to do that with the TargetReport folder,Target server url.,

    Thanks,

    Rajdiep

  13. Anonymous says:

    This looks great. I need to do exactly what you have here. But I don’t know c# at all. Do you possibly have this also in vb.net?

  14. Anonymous says:

    Hi

    I am not getting the design view file of textboxes in the solution.i am not getting view|user interface,view|custom action etc.please guide me….so that i can view these files

  15. Anonymous says:

    I need to deploy the reports to a machine that with no VS installed. Will this MSI work?

  16. Anonymous says:

    I have developed a tool for publishing reports automatically, based on a XML configuration file; check it out here:

    http://blogs.ugidotnet.org/dsenatore/archive/2008/10/01/94219.aspx

  17. Anonymous says:

    Hi!

    I need to set the reportserver url at runtime(using an XML file eg: http://servername/reportserver).

    Can we do this in your solution?

  18. charanjit kaur says:

    I have deployed my reports and database to the URL, but i have to deploy databse every day else it generates blank report. pls help and provide some solution for the same,.

  19. Anishsharaf says:

    Hi,

    for me the datasource is not createtd on the reportserver

    but the sample.rdl and the msi folder got created ..

    Please help me on this.

    Thanks,

    Anish

  20. copy Image says:

    How can i copy an image file   to the folder in reportserver

  21. Mark Freeman says:

    Given that  Microsoft has deprecated VS setup and installer projects, what would be the best mechanism for creating a report installer for my application using technologies that will still be around after the next release of VS? (From msdn.microsoft.com/…/ee721500.aspx, "Future versions of Visual Studio will not include the Visual Studio Installer project templates.")