I was working on a project a few months ago and when it came time to deploy, the client wanted to connect to any MS SQL server no matter where they were. Sometimes this server would be local, other times it would not. The IP address might change depending upon which machine it was installed on, and where you were at. So needless to say the client needed an application that could install easily, and allow the setting of the applications connection string during the installation process.
During my time on this part of the project, I looked all over the Internet for something to help me, but to no avail. So I decided I would write a little walk-through to help anyone else in this situation. Let’s get started.
Step 1 – Make a Setup Project
Okay lets start off by adding a setup project to our current solution. If that sounds confusing don’t worry, it might be. You should already have a solution open, that you’re working in. This would be the software application that you want to deploy, and the application that the connection string need’s to be changed based on installation conditions. So in any event, my application looks like this after i have created a setup project. (Ignore the popup in the middle of the screenshot.) So now you can see that we have added a setup project to our main solution. I called mine PETSetup, PET being the inital project that I wish to delpoy.
It should automatically detect dependancies from your solution and inform you of other resources it will need for the project. One of the most improtant things to include with the setup project is the .NET 2.0 installation. You can leave it out, however if the person installing the product does not have .NET 2.0 framework installed, it will promt them to download it from microsoft. This is usually a hassle for the person installing your software, so just package it together unless you need to keep the install smaller.
The way that you generally navigate around a setup project is by right clicking the project itself. So when i right click “PETSetup” I get a nice little menu. The parts were worried about here is “View” and “Add”. These are where the magic happens in a setup project, you can view different areas of the setup, like the registry entires, UI flow, and other things. I bet you cant guess what you can do with Add, yep, you can add all those things we just mentioned. I will touch on each section a little bit, maybe I can write in more detail in another tutorial, but here is a quick over view.
File System View
In this view you can see what the user is going to have installed on their machine. It allows you to create start menu items, and desktop shortcuts as well as a few other things. Mainly you want to make sure that you have a start menu icon, and a desktop icon for most applications. In fact, it would be even better if you could ask if they want those things before you just throw them all over your users computers.
Registry
Using this view you can tell the installation to add system registry keys. If you don’t know what you’re doing here you can really mess things up so make sure that you’re sure of what you need from this view before you do anything. These are system wide variables that handle system critical information about the operation of you computers software, so don’t change these if you don’t know what they are.
File Types
This is where you tell your setup project what file types are associated with your application. Ever wonder how .doc files get associated with Microsoft Word? They use something like this to tell windows, “hey, all these .doc files open with our program.” Needless to say you can take association away from files that may already have an association with something else, so be careful.
User Interface
In this view, you can see exactly how the installation will flow. This is kind of weird at first as there are two flows you can see, one of them is for a normal user, the other is for the administrator. So if you are making a new installation and both setups need to be the same, make sure you make the additional changes to BOTH setup UI’s or else some of you users are going to get errors.
Custom Actions
I still havent dove all the way into custom actions, these tell the setup what they need to run after certain things happen. So you can tell the setup to roll back some database changes if you have a database installed but they cancel the installation. Really, this is mainly for telling the setup what stuff it needs to run outside of itself, when certain install events happen.
Launch Conditions
In this view we can see what our launch conditions are, imagine that. If you have something that you require from your application like…. Microsoft SQL Express Server, you can add this to the launch conditions and if they end up not having it, they will be notified. Be careful not to add launch conditions, that you don’t bundle with your installation. For instance, if you need SQL Express to run your application, don’t give your installation out, or setup a launch condition, without packaging that inside your setup. You dont want you users to stop installing your program just so they can go download some huge file and install something else.
Step 2 – Making our Custom Installation Dialog
Okay, so by now you have that setup project added to your solution. If you right click on the setup project, and select “Install” it will run for you and you’ll be able to see exactly what it does. When you get done, you can right click and hit “Uninstall” to make sure your program uninstalls correctly. In any event you will notice that there are a set of dialogs that microsoft already has there. If we want to add to these, unfortunately it’s just not as easy as right clicking and adding a new form to our setup project.
Since the project I’m installing is “PET” I know that after I have it installed its actually on the users system, in a location that they specified. So we know that the app.config file (where the connection string resides) is in the directory as well. Before we actually get to editing that, we need to create a form in the project were installing that will handle the input of our connection string. Here is what i made:
This form will take in our datasource, username, password, and then print out the connection string as it’s being built to show the user what it looks like, and in case they want to copy it. (In this case we are making a more technical setup, normally you would hide the connection string, and do it all on the back end.) I also have a check box to let them tell the application if the database is local or not. If it is were going to have a different conneciton string, than if it’s not.
Once that is completed you are ready to move onto the Installation.cs file step 3.
Step 3 – Installation File
In order for out setup project to know that we have an item in our installed project that needs to be run, we make an installer class file. I called this file Installer1.cs It looks something like this:
namespace Pet { [RunInstaller(true)] public partial class Installer1 : Installer { public Installer1() { InitializeComponent(); Form frm = new frmDBSetup(); frm.BringToFront(); frm.ShowDialog(); } } }
This code is really simple, the important part is [RunInstaller(true)] this tells our installer that we want it to run this cose, at a specified time (which we’ll get to later) in our installation. Take note of the use of public partial class, and that it inherits from the Installer class.
As you can see the code has a constructor that makes a new db setup form (from setup 2) and brings the form to the front, and shows it as a dialog. You need to make sure you show it as a dialog instead of a form, so they MUST enter information before they can go back and mess around with the installation. Now you’re ready to move on to the final step.
Step 4 – Custom Actions
We now need to create a custom action to tell our installer to run our new installer.cs file. Go back to your setup project, right click it, select view, and then select “Custom Actions.” Once the screen comes up, right click on the Install file, and select “Add Custom Action.”
The next dialog is kind of confusing so I’ll explain it a little bit here. Since were dealing with an installation, there is no regual file view, or paths, it’s all relative to the installation. So were not presented with hard drives or CD drives, we have different folders for different areas of the installation. In our case were going to select the Application Folder. The next screen will show you all the files that are located in the Application Folder after it is installed on the client machine. What we want to do is make sure that our installer1.cs file is run, so we want to select the “Primary output from PET (Active)” in my case. After that click okay, it should have added to your installation custom actions screen and should look something like this:
Here is where i would take the time to test the installation. Your form currently doesnt do anything but you can at least see that its going to come up when you run the installation. Now we can move on to making the database setup form alter the app.config file to create a custom connection string.
Step 5 – Editing the app.config connection string from installation
Well you made it this far don’t turn back. You’re almost finished but unfortunately I saved the hardest part for last. I wont go into all the details about how to setup the code, for that i will let you just download the .cs file, its easier than pasting it here and formatting it out for hours on end. But i can go over the important parts. I would recommend having file in front of you here it is: frmdbsetup.doc (In doc format since thats what wordpress allows.)
The most important part of the file is the finish button click event, locate it at the bottom of the frmDBsetup.cs file. Let’s take a look at how we alter the app.config:
Configuration c = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetExecutingAssembly().Location); ConnectionStringsSection section = (ConnectionStringsSection)c.GetSection("connectionStrings"); section.ConnectionStrings["netTiersConnectionString"].ConnectionString = connectionString; c.Save();
So we start off by making a new instance of the Configuration. Where the real magic happens here is in the System.Reflection.Assembly area, this tells the installer that were going to find the path of where the assembly its executing. Since were launching our dialog, from the application folder, no matter where they install the application, this will give us the path to the directory of the app.config, and esentially their application itself. Pretty neat huh? Once we have the directory, we are free to go about whatever we want. We finish by using the connection string section, it basically grabs the connection strings out of the app.config, and then we just make sure to add our own connection string that we built based off of our nice little dialog form from step 2.
All Done!
Thats about it, its really not as hard as it seems. There are a lot of questions that come about with deployment of applications, one of the biggest ones is how do you alter stuff after installation. Now you know! You can use this same proccess to do anything you need after installation, the possibilites are endless. I hope you enjoyed learning, and I hope I made everything clear, if you have any questions or commends don’t hesitate to ask. Thanks!
very interesting.
i’m adding in RSS Reader
thanks a lot man..i was lukin fr xactly this article….but lemme ask u one qstn..i dunno whtr im corct or not..Instead of modifyng th the conctn string at the time of instalation, y cant we allow the provision for modifyin it at the time of running the prog? wont that luk nice..? what i realy meant was u’l be doin al this modifications in the app.config file at the time of runnnin the app..?isnt it possibl to change the app.config file thn..?
What the hell does this even say?
If you type out the full words people are more likely to help you.
This line are showing error
Configuration c = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetExecutingAssembly().Location);
ConnectionStringsSection section = (ConnectionStringsSection)c.GetSection(“connectionStrings”);
The namespace is missing
nice writeup.. it helped.
Thanks for the comments, i noticed the hits on this particular article go up a lot over the last few months, and i never got any feed back! It’s nice to know it helped someone else out!
Thanks for a helpful tutorial on a poorly documented subject. I found the tip on using the reflection API to locate the user’s config file especially useful.
Wade,
Very nice writeup! I found the approach to be very helpful, however I believe you have made one minor error that isn’t manifesting itself in your example because you have only defined the Install Custom Action. If you happen to use the same class for Commit, Rollback, and Uninstall, you will fire the Form each time you hit one of those Custom Action methods. To solve this problem, you can simply move the Form code into an Install method.
– DonahueM
You are correct! This is still a bug in the final application that i wrote this installer for! You would definitely want to make different classes for those actions based on what your installer is going to do. That way if you change a database, files, or registry on the users system and they cancel… it will rollback your applications changes. If you don’t you may cause errors or other problems which would definitely not be a good thing for a clients machine!
Thanks for pointing that out!
Thanks for your tutorial. It helps me a lot.
Is the ConnectionString readonly? May I change the it like this:
section.ConnectionStrings[“netTiersConnectionString”].ConnectionString = connectionString;
Is there anybody tried it successfully ? Thanks.
hi,
first, sorry for my english…:)
I have made an Installer Class, it works, but my trouble is when the user want to stop the installation, it doesn’t stop… I have a message, but the installation goes on.
I have made method override for “RollBack” , but the programm doesn’t get in on clicking Cancel_Button.
How can I made for stopping or calling the rollback method, when the Cancel_Button is clicking?
thanks
This is very helpful for me ..Thanks
Thanks for the comments everyone,
Geof, I’m not sure exactly what could be happening with your current situation. I have a feeling its something to do with the event thats fired, maybe it possibly isn’t triggering the roll back method that you have overridden. If you are trying to call the roll back method from a form which you created, you may need to send a message back to the actual installer class telling it you are cancelling the installation in order for it to properly roll back.
Let me know if this helps!
this article is good hepled me….. but i need little bit more explanation of.. how to message back to installer class to let it know that the user has cancled the installation processs……. it’ll be very heplfull if u could give some example with code……………
thanks wlasson………..
does this implementation handle silent installs? In a similiar solution I implemented, I was forced to query the installerContext “UILevel” property to detect if the custom action was being run from a silent installation. In that case, you definitely would not want to display a dialog…
e.g.
public override void Install(System.Collections.IDictionary savedState)
{
base.Install(savedState);
if (Convert.ToInt32(Context.Parameters[“UILevel”]) > 3)
{
ConnectionStringsDialog dialog = new ConnectionStringsDialog(this);
dialog.BringToFront();
dialog.ShowDialog();
}
}
sss
I am not getting any response from your given code.
How can I access these Parameters (Datasource,Username,Password) ?
How can I Configure the App.config file by webservices?
Hi
My Another ??? is
I have API web Services ….
How to Configer it in app.config file ……
My Have Acess the “DataBase , Stored Procedure ” through the ProxyServices ,
How it Configer in app.config file……in above writen Your Code…….
Hi,
This post is really important.It worked fine with my problem which was to create a connection string that was given to users to update their own connection string.
Keep up the good work.
Thanks
thanks for ur article,, i really needed it for my first project..(in my university)
I am working on a windows forms app. I do my development in a development environment, and I have certain settings in my app.config like connection strings that point to my development SQL server.
When I deploy my Application with ClickOnce, those settings are going to have to be updated to their production values. What is the recommended method for managing this? I can’t imagine modifying the app.config on production and then having to start over again with the development values the next time i publish.
thanks in advance
The write is really good.
I have a question here. The form call is written in the constructor – that means while i do uninstall this form would be again displayed. Is there a way that i can stop this form from displaying while uninstall??
Thanks in Advance.
hi
Read ur article its nice….i am having a doubt…i created a windows application setup…
i checked for dotnet frame work and MySql file is present in the system or not…
if My Sql not present in the system it will pop up Install MySql… I need to know how to include MySql setup in this application setup project…
Pls help me if any one know the answer…
thanks in advance
i understod but where can i create the Installer class and also the connection form. i can’t create inside the setup project.
Great walkthrought ,
use it but with a oracle connection, great results. Open a lot of possibilities.
Yossef you need to create it in your application projet .
thanks
Hi,
This is very nice article and I am looking for the sample code to download. Do you have it anywhere? Thanks.
I have since lost the code to this tutorial, however this is the only file for the actual setupdbform, hopefully it has what you need:
https://wlasson.files.wordpress.com/2007/05/frmdbsetup.doc
Good one.it is very helpful.
I am not able to cancel the installation while doing this
Thanks alot much helpfull thanks again
Thanks thanks thanks thanks thanks thanks thanks thanks thanks thanks thanks thanks thanks. This was really helpful! =)
My program gives an error at this point:
section.ConnectionStrings[“netTiersConnectionString”].ConnectionString = connectionString;
error:”object reference not set to an instance of an object”
any ideas?
[…] see a range of options. I just spent an hour on this and quickly settled on the method used by Wade Lasson in his blog. He adds a windows form to the project to be installed (not the setup project) which […]
thanks a lot man..i was lukin fr xactly this article….but lemme ask u one qstn..i dunno whtr im corct or not..Instead of modifyng th the conctn string at the time of instalation, y cant we allow the provision for modifyin it at the time of running the prog? wont that luk nice..? what i realy meant was u’l be doin al this modifications in the app.config file at the time of runnnin the app..?isnt it possibl to change the app.config file thn..?
You could modify the connection string at the time of first launch, however i always feel like for a better user experience they should do this during the installation. Then once they run the application they are already setup, and good to go!
I noticed a lot of questions about writing it to the app.config, you can do this the same was a writing a normal variable to the app.config, you would need to do this within your setup form that you customize inside the project.
Thanks for the comments everyone!
Very Good one
Big help. Thanks for taking the time to write it up.
It is realy helpful but I want the same solution for c# 3.0 can any one help me?Please if any one know how to create setup through c# windows application(I hav c# application with finish button ,on click event i want to build setup for my application ) please help me
Thanks for this helpful article. Its a big help i think.
I need to add an uninstall menu in the program menu for my Custom Installer (Setup Project) so that the user can uninstall this software without going to control panel.
How can I do that? Please help me.
The instructions above should work for 3.0 without much modification, i know a few things changed but the basic functionality should still be the same. Maybe i will take some time and write one up for 3.0+ since this post is so popular.
For uninstallers you may want to think about just simply making a custom installer launch page that will invoke the uninstall commands for you. For example, before the install launches you have a window with two options, re-install and remove. Then you just need to wire them appropriately!
I can’t provide code examples at the moment but i hope that’s enough to point you in the right direction.
Nice Article !
Here, I want to know one thing that is it possible to show the new input form in sequence with the other setup forms instead of showing it as a dialog box ??
I mean, how can we make the new input form as a sequential part of the wizard itself ?
I’m not 100% sure how to do this, in the tutorial I chose this way of working around that for the simple fact that it did what we needed and made it easier than trying to work with something that is pre-built. However, with the improvements and new releases there may be a more simple way to do this. I’m not sure i have an answer to your question though I apologize!
Great article. I could not find the solution on web even at Microsoft.
Great site dude! Been searching for a site like this.
I missed myself in the past three days for creating custom user interface.
your artical is so helpful for me. Thank you very much.
Very good article.
But if I need, save the changes the string connection in the App.config file at the moment of install my project. Is possible?
thanks.
Fantastic decription. So concise and much more helpful that msdn. Worked first time. Thank you so much for your efforts.
My program gives an error at this point:
section.ConnectionStrings[“netTiersConnectionString”].ConnectionString = connectionString;
error:”object reference not set to an instance of an object”
any ideas?
Thanks in Advance…..
It looks as though you may not have the connection section for “netTiersConnectionString” setup at this point in the web.cofing / machine.config. I would imagine when you debug this that “connectionString” has a value, but: section.ConnectionStrings[“netTiersConnectionString”] does not have a value, and is null. Ensure that at this point during installation you have that line in the machine or web.config. It is possible that those items might not have had a chance to be put in place before you call the custom form.
If i was working on the error you see, i would debug down into the custom form to that line and see what things look like within the folder structure and what has actually been completed and what hasn’t. Hope that helps, feel free to ask more questions if you need to!
This is very good! Thanks a lot.
Thank you very much for this. I do not develop professionaly, but have taken a few classes at community college.
I built a nifty, simple program for managing my library, and my girlfriend’s (we have around 1000 books on shelves at the moment, more on loan, and some in storage…) and couldnt get it to work. This did the trick!
Thank you VERY much!
Nice Writing Thanks
Good,
Thank you very much for this.
[RunInstaller(true)]
public partial class Installer1 : Installer
{
public Installer1()
{
InitializeComponent();
Form frm = new ConnectionString();
frm.BringToFront();
frm.ShowDialog();
}
}
InitializeComponent(); is showing error.
error msg -The name ‘InitializeComponent’ does not exist in the current context D:\PrintDataGridView\PrintDataGridView\InstallerConnectionString.cs
wht is the solution for it.?
What version of .NET are you currently using? This was written back in ye’ olden days of .NET and it may be a compatibility issue with newer versions.
I’m currently in the process of writing a new tutorial like this for .NET 4.5 but progress has been slow as of late.
Is it good for .Net 4.5?
I haven’t tried compiling this with 4.5. My assumption is that it probably doesn’t work verbatim, but i am in the process of finishing up my 4.5 tutorial. I’m hoping to post that within a few weeks, time permitting. If anyone does happen to try this in 4.5 post a comment, i’d be interested to see if it works and/or what changes you make to get it to work.
Çok iyi bir paylaşım olmuş sağolun
I got the solution for my problem But when i enter those inputs while installing it throws exception saying object reference not set to an instance of an object.
Please help me