Click here to Skip to main content
15,795,789 members
Articles / Desktop Programming / Windows Forms

Extending Visual Studio Setup Project

Rate me:
Please Sign up or sign in to vote.
4.88/5 (66 votes)
16 Jan 2011Ms-PL4 min read 249.8K   9.8K   235   45
Extending Visual Studio Setup Project for Building Reliable Windows Installer (MSI)


One of the things I hear all the time when companies talk about building reliable Windows Installer (MSI) for their product is –> Visual Studio Setup Project is not enough and we need much much more, my first response is – Wait, VS Setup project is not like Advanced Installer, InstallShield but still can do a lot more outside the box.

Setup projects are used to create Windows Installer (.msi) files, which are used to distribute your application for installation on another computer or Web server. There are two types of setup projects:

  • Standard setup projects create installers that install Windows applications on a target computer.
  • Web setup projects create installers that install Web applications on a Web server.

In this article, I’ll show how to extend your VS Setup Project and help to understand how VS Setup makes it easy for developers to build reliable Windows Installer (MSI) in Visual Studio. (All my screenshots will take from Visual Studio 2010.)

  1. Getting Started With VS Setup Project
  2. Adding New User Dialog and Deployments Conditions
  3. Run External Application during Setup

Getting Started

Open Visual Studio and create new Setup Project called – "DemoSetup", the Setup project item can be found under "Other Project Types"-> "Setup and Deployment" –> "Visual Studio Installer".

Also create a WPF application called – "DemoWpfApplication", we need some project to work with.

Two things need to be done in order to get the MSI ready for deployment.

  1. On the DemoSetup project, Add Project Output from DemoWPFApplication – Setup will automatically find all related dependencies.
  2. Modify Setup Project properties (See picture below)

The Version Property is very important for various MSI, in order to identify old installation and overwrite existing files with a newer version.


Adding New User Dialog and Deployments Conditions

Now, this is one of most common improvement users always want – Add an additional Dialog during the setup and add your own questions or input.
In this step, I’ll show how to add conditions and add a new user Dialog, here are the requirements: Add the following file (Dummy Files):

  • Blue.bmp,Red.bmp, Green.bmp
  • License.rtf
  • "Readme for 2000.txt", "Readme for Windows 7.txt"

1. First Let's Add Our Product License Agreement

Select the Setup Project and click "User Interface Editor" icon:


This will open a view showing all the dialogs the user will see during the Setup process.
Click "Add Dialog" and choose "License Agreement", after adding this dialog view dialog properties and select the License.rtf file.


2. Add Deployment by Condition

Add deployment condition for "Readme for 2000.txt", "Readme for Windows 7.txt", the propose is to copy each file only for specific operation system.
Select "Readme for 2000.txt" to see his properties, locate Condition and add this command –

WindowsBuild = 2195 or VersionNT = 500 

Now select "Readme for Windows 7.txt" and add this in the Condition property –

WindowsBuild >= 7100 or VersionNT = 601 

(More information on Operating System Property Values)
The condition will allow you to copy specific file depending on the user OS.

3. Add your User Choose Condition

This step will show you how to add your own questions (using Radio Buttons) and allow the user to define a Favorite Color and use User choose as condition for deployment.
Add a new Dialog and choose "RadioButton (3 buttons)" add fill the information as below:


To add the condition, you need to select each of the following files: Blue.bmp, Red.bmp, Green.bmp and add the proper value in the condition property as follow - FAVORITECOLOR="Blue", FAVORITECOLOR="Red" etc.

Build the setup project and run it, select Green in "Favorite Color" and the result should look like:


Run External Application during Setup

In this step, I’ll show how to run an external application before the actual install process using "Installer Class".
Create new WPF Application project called – "SetupHelper" and add additional Item of type "Installer Class" called – "MyInstallerHelper".
The InstallerClass will allow you to override the following events:

  • Rollback
  • Install
  • OnAfterInstall
  • Commit
  • OnAfterRollback
  • OnAfterUninstall
  • OnBeforeRollback
  • OnBeforeUninstall
  • OnCommitted
  • OnCommitting
  • Uninstall
  • OnBeforeInstall

First, add your code for "SetupHelper" WPF application, I’ve added code to show current processes and process title, but you can add whatever you want.
Now we need to add "SetupHelper" WPF app to our setup project, select the Setup Project and "Add Project Output" of SetupHelper.
Select the Setup Project and click on the "Custom Actions Editor" icon:


On the install, add new "Custom Action" and from the "Application Folder", pick "Primary output from SetupHelper (Active).
Now select the new Custom Action and in the "CustomActionData", add the following -

/Run=SetupHelper.exe /WaitForExit=true 

Back to MyInstallerHelper, override OnBeforeInstall and paste the code below in order to get the CustomActionData you wrote above:

protected override void OnBeforeInstall(IDictionary savedState)
        FileInfo fileInfo = new FileInfo
        //Take custom action data values
        string sProgram = Context.Parameters["Run"];
        sProgram = Path.Combine(fileInfo.DirectoryName, sProgram);
        Trace.WriteLine("Install sProgram= " + sProgram);
    catch (Exception exc)

OpenWithStartInfo will run SetupHelper application and will pause the setup process while the SetupHelper is open.

void OpenWithStartInfo(string sProgram)
    ProcessStartInfo startInfo = new ProcessStartInfo(sProgram);
    startInfo.WindowStyle = ProcessWindowStyle.Normal;
    string[] ExcludeKeys = new string[] { "run", "WaitForExit" };
    startInfo.Arguments = ContextParametersToCommandArguments(Context, ExcludeKeys);
    Trace.WriteLine("run the program " + sProgram + startInfo.Arguments);
    Process p = Process.Start(startInfo);
    ShowWindow(p.MainWindowHandle, WindowShowStyle.Show); 	//otherwise it is 
							//not activated 
    BringWindowToTop(p.MainWindowHandle); 	// Make sure the user will see 
					// the new window above of the setup.
    Trace.WriteLine("the program Responding= " + p.Responding);
    if ((Context.IsParameterTrue("WaitForExit")))
        p.WaitForExit();// Have to hold the setup until the application is closed.

ContextParametersToCommandArguments gets the CustomActionData arguments you added in the Custom Action.

public static String ContextParametersToCommandArguments
		(InstallContext context, string[] ExcludeKeys)
    ExcludeKeys = ToLower(ExcludeKeys);
    StringBuilder sb = new StringBuilder();
    foreach (DictionaryEntry de in context.Parameters)
        string sKey = (string)de.Key;
        bool bAdd = true;
        if (ExcludeKeys != null)
            bAdd = (Array.IndexOf(ExcludeKeys, sKey.ToLower()) < 0);
        if (bAdd)
            AppendArgument(sb, sKey, (string)de.Value);
    return sb.ToString();

public static StringBuilder AppendArgument(StringBuilder sb, String Key, string value)
    sb.Append(" /");
    //Note that if value is empty string, = sign is expected, e.g."/PORT="
    if (value != null)
    return sb;

#region "FS library methods"
public static string[] ToLower(string[] Strings)
    if (Strings != null)
        for (int i = 0; i < Strings.Length; i++)
            Strings[i] = Strings[i].ToLower();
    return Strings;
#endregion //"FS library methods"
#region "showWindow"

static extern bool BringWindowToTop(IntPtr hWnd);

[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);

private static extern bool ShowWindow(IntPtr hWnd, WindowShowStyle nCmdShow);

/// <summary>Enumeration of the different ways of showing a window using 
/// ShowWindow</summary>
private enum WindowShowStyle : uint
    Hide = 0,
    ShowNormal = 1,
    ShowMinimized = 2,
    ShowMaximized = 3,
    Maximize = 3,
    ShowNormalNoActivate = 4,
    Show = 5,
    Minimize = 6,
    ShowMinNoActivate = 7,
    ShowNoActivate = 8,
    Restore = 9,
    ShowDefault = 10,
    ForceMinimized = 11

Try It

Now Run the Setup project and you will notice that during the installation process, your Setup Helper will pop up and prevent the Setup from continuing until you will close the application.


After the setup is complete, you will see your setup output as below:



As you saw in this article, Visual Studio Setup Project can be extended a lot more and this can be good for many applications.


  • 16th January, 2011: Initial post


This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Written By
Architect Sela
Israel Israel
Shai Raiten is VS ALM MVP, currently working for Sela Group as a ALM senior consultant and trainer specializes in Microsoft technologies especially Team System and .NET technology. He is currently consulting in various enterprises in Israel, planning and analysis Load and performance problems using Team System, building Team System customizations and adjusts ALM processes for enterprises. Shai is known as one of the top Team System experts in Israel. He conducts lectures and workshops for developers\QA and enterprises who want to specialize in Team System.

My Blog:

Comments and Discussions

AnswerRe: How to change startup info for the setup project Pin
Sofigolu0117-Nov-14 5:09
Sofigolu0117-Nov-14 5:09 
QuestionHow could i make opened window as Modal? Pin
Sunasara Imdadhusen28-Aug-11 22:55
professionalSunasara Imdadhusen28-Aug-11 22:55 
AnswerRe: How could i make opened window as Modal? Pin
Shai Raiten29-Sep-12 21:37
Shai Raiten29-Sep-12 21:37 
GeneralMy vote of 5 Pin
jawed.ace19-Jun-11 22:51
jawed.ace19-Jun-11 22:51 
GeneralRe: My vote of 5 Pin
Shai Raiten20-Jun-11 6:36
Shai Raiten20-Jun-11 6:36 
QuestionRe: My vote of 5 Pin
Johnny7929-Jun-11 9:32
Johnny7929-Jun-11 9:32 
AnswerRe: My vote of 5 Pin
Shai Raiten30-Jun-11 22:23
Shai Raiten30-Jun-11 22:23 
GeneralMy vote of 5 Pin
yoave2317-Apr-11 1:32
yoave2317-Apr-11 1:32 
Great article.
is there any way to include .net framework or sql server express installations in the setup project?
GeneralRe: My vote of 5 Pin
Shai Raiten2-May-11 2:21
Shai Raiten2-May-11 2:21 
GeneralMy vote of 5 Pin
David Veeneman8-Apr-11 5:47
David Veeneman8-Apr-11 5:47 
GeneralVery interesting Pin
Paolo Foti18-Feb-11 3:08
Paolo Foti18-Feb-11 3:08 
Generalobfuscation Pin
Kubin15-Feb-11 21:13
Kubin15-Feb-11 21:13 
GeneralRe: obfuscation Pin
Shai Raiten18-Feb-11 22:29
Shai Raiten18-Feb-11 22:29 
GeneralMy vote of 5 Pin
dr_eck17-Jan-11 6:07
dr_eck17-Jan-11 6:07 
GeneralRe: My vote of 5 Pin
Shai Raiten17-Jan-11 9:59
Shai Raiten17-Jan-11 9:59 
Generalthanks for sharing - have 5 Pin
Pranay Rana16-Jan-11 21:20
professionalPranay Rana16-Jan-11 21:20 
GeneralRe: thanks for sharing - have 5 Pin
Shai Raiten17-Jan-11 10:00
Shai Raiten17-Jan-11 10:00 
GeneralMy vote of 5 Pin
kdgupta8716-Jan-11 8:05
kdgupta8716-Jan-11 8:05 
GeneralRe: My vote of 5 Pin
Shai Raiten17-Jan-11 10:01
Shai Raiten17-Jan-11 10:01 
GeneralMy vote of 5 Pin
Valery Possoz16-Jan-11 7:49
professionalValery Possoz16-Jan-11 7:49 
GeneralRe: My vote of 5 Pin
Shai Raiten17-Jan-11 10:01
Shai Raiten17-Jan-11 10:01 

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.