No more setup project template in Microsoft Visual Studio 2011, Microsoft all in on marketplace?


I can’t find setup project templates in the Microsoft Visual Studio 2011 developer preview and Microsoft says the following on the Visual Studio Setup project templates:


Future versions of Visual Studio will not include the Visual Studio Installer project templates. To preserve existing customer investments in Visual Studio Installer projects, Microsoft will continue to support the Visual Studio Installer projects that shipped with Visual Studio 2010 per the product life-cycle strategy. For more information, see Expanded Microsoft Support Lifecycle Policy for Business & Development Products.


Is this because Microsoft wants you to distribute your applications by using the Microsoft Marketplace?

Overwriting the msiexec property TARGETDIR for x86 and x64 application setups

If you want to remove a application from you’re system you can use:

msiexec /x {product_guid}
like: msiexec /x {2EAB2958-5675-4773-9BF6-2C8FB9DF9CC6}


If you want to install a *.msi package, but want don’t want to install the application to the default installation folder you can overwrite the TARGETDIR property, like

msiexec /i "C:\Temp\MyFirstApp.msi" TARGETDIR="D:\Programs\MyFirstApp"

But if you’re msi package is created with Microsoft Visual Studio and the property Targetplatform of the setup project is set to x86, you can’t overwrite the TARGETDIR to Program Files, when you execute the following line on a x64 machine:

msiexec /i "C:\Temp\MyFirstApp.msi" TARGETDIR="C:\Program Files"


The msiexec will change it back to "C:\Program Files (x86)"


Just so you know why the application is installed in the "C:\Program Files (x86)" folder instead of the "C:\Program Files" folder.

Extract contents of msi packages in C#

If you want to extract the contents of a msi package to filesystem, you can use the following C# function:


public void ExtractMsiPackage() {    string parameters = string.Empty; parameters = string.Format(@"/a {0} /qb TARGETDIR=""{1}"" REINSTALLMODE=amus",

"C:\Temp\Test.msi", "C:\Temp\Extract"); Process process = Process.Start("msiexec", parameters); process.WaitForExit(); }

/a = Administrative mode

/qb = Minimal UI, UI will only display progressbar

TARGETDIR = Folder to extract the contents to

REINSTALLMODE = amus, will overwrite all existing files and registry settings

Microsoft Visual Studio Setup prerequisites, launch conditions and the .NET Target Framework 4 Client Profile

When I changed the prerequisites for my Microsoft Visual Studio setup project to target the .NET Framework 4 and not the .NET Framework 4 Client Profile, I got the message:

The target version of the .NET Framework in the project does not match the .NET Framework launch condition version ‘.NET Framework 4 Client Profile’. Update the version of the .NET Framework launch condition to match the target version of the.NET Framework in the Advanced Compile Options Dialog Box (VB) or the Application Page (C#, F#).


This was caused by the fact, that the setup Launch condition was still on Microsoft .NET Framework 4 Client Profile



Change the Setup Launch condition to match you’re setup prerequisites:

  • Select you’re project in the Solution Explorer
  • Click on the Launch Conditions Editor button



Note 1

You can change the prerequisites of you’re Microsoft Visual Studio setup project, by right clicking on the setup project, choose properties and click on Prerequisites…



Change to Microsoft .NET Framework 4 and not Microsoft .NET Framework 4 Client Profile:



Note 2

When you are working with Microsoft Visual Studio setup projects make sure the following settings are in sync:

– Project Target framework for the projects the setup references

– Prerequisites of the setup project

– Launch condition of the setup project

PowerShell function to update a .net C# application, by using a setup package (*.msi), without changing the setup package version

The output of a Microsoft Visual Studio Setup Project is a setup package (*.msi). If you run this setup package on a system, you can’t re-install the package on that system, without changing the version of the setup package. If you want to update the .net C# application without changing the version number, you can use the following PowerShell script:


function DeploySubsystem([string]$name, [string]$msiPackageProductCodeGuid, [string]$msiPackagePath)
    "Uninstall $name"
    $parameters = "/qn /x $msiPackageProductCodeGuid"
    $processPath = "msiexec"
    "Run [$processPath $parameters]"
    $process = [System.Diagnostics.Process]::Start( $processPath, $parameters )

    "Sleep for 5 seconds to make sure the system has updated the registry"

    "Install $name"
    $parameters = "/qn /i ""$msiPackagePath"""
    $processPath = "msiexec"
    "Run [$processPath $parameters]"
    $process = [System.Diagnostics.Process]::Start( $processPath, $parameters )


To call the function use:

DeploySubsystem "MyFirstApplicaiton" "{396E89DB-5E5C-4781-9E88-0FEC56D9C06C}" "C:\Temp\MyFirstApplication.Setup.msi"   

Microsoft SQL Server 2008 R2 setup starts, when you build a Visual Studio 2010 setup project

When you build a Microsoft Visual Studio 2010 setup project a Microsoft SQL Server 2008 R2 setup might start. To solve this problem on a x64 system:

regsvr32.exe /u "C:\Program Files (x86)\Common Files\microsoft shared\MSI Tools\mergemod.dll"
regsvr32.exe "C:\Program Files (x86)\Common Files\microsoft shared\MSI Tools\mergemod.dll"

on a x86 system

regsvr32.exe /u "C:\Program Files\Common Files\microsoft shared\MSI Tools\mergemod.dll"
regsvr32.exe "C:\Program Files\Common Files\microsoft shared\MSI Tools\mergemod.dll"

Remove item from Programs and Features list in Windows 7

If the uninstallation of an program fails, the item will not be removed from the “Programs and Features” list on the Control Panel in Windows 7.

To remove the item, remove the item from the registry key:

Windows 7 x64



Windows 7 x86




Removing the key will only remove the item form the “Programs and Features” list, if you want to re-install the program you should also find the productcode and the corresponding upgrade code, then remove the entry from:


How to detect unattended installation (msiexec /quit or /qn) in you’re Custom Action with C#

Set UILevel property in CustomActionData, enter: /UILevel="[UILevel]"


A msi package can be started with different user interface types. For instance, a *.msi package started with msiexec /quit /i Example.msi, will have an UILevel = 2, but the same *.msi package started with msiexec /i Example.msi will have an UILevel = 5, see

User interface level Value Description
msiUILevelNoChange 0 Does not change UI level.
msiUILevelDefault 1 Uses default UI level.
msiUILevelNone 2 Silent installation.
msiUILevelBasic 3 Simple progress and error handling.
msiUILevelReduced 4 Authored UI and wizard dialog boxes suppressed.
msiUILevelFull 5 Authored UI with wizards, progress, and errors.
msiUILevelHideCancel 32 If combined with the msiUILevelBasic value, the installer shows progress dialog boxes but does not display a Cancel button on the dialog box to prevent users from canceling the installation.
msiUILevelProgressOnly 64 If combined with the msiUILevelBasic value, the installer displays progress dialog boxes but does not display any modal dialog boxes or error dialog boxes.
msiUILevelEndDialog 128 If combined with any above value, the installer displays a modal dialog box at the end of a successful installation or if there has been an error. No dialog box is displayed if the user cancels.

If you want to detect de UILevel of you’re executed msi package, during the execution of the msi package in a custom action follow the steps:

  • At a System.Configuration.Install.Installer to you’re project
  • image
  • Make sure the System.Configuration.Install.Installer has the attribute [RunInstaller(true)] set
  • Make sure the System.Configuration.Install.Installer has event handling wired up for the events you whish to handle (in this case I want to run code “AfterInstall” and “BeforeUninstall”
  • image
  • At a setup project to you’re solution
  • At the output and content files of you’re project to the setup project
  • image
  • Add custom actions (so the System.Configuration.Install.Installer events are fired)
  • image
  • image
  • Click on the custom actions and set the UILevel to /UILevel="[UILevel]" in the CustomActionData on the property page
  • image
  • In you’re “AfterInstall” event handler you can know access user interface type of the executed msi package, via this.Context.Parameters[“UILevel”]
  • Msi parameters are case sensitive so use “UILevel”
  • private void AfterInstallation(object sender, InstallEventArgs e)
    #if DEBUG
                // Break when in debug modus
                string uiLevel = this.Context.Parameters["UILevel"];

Create custom eventlog during setup, by reading log4net configuration file.

If you want to create a customeventlog during setup, in a custom action. You can open a App.config file containing the log4net configuration and read the settings from that file at runtime.
You also can add appenders or remove appenders at runtime, but in this case I just wanted to read the configuration and create a custom eventlog:

       private string _productInstallationFolder = null;
       /// <summary>
       /// Returns C:\Program Files\MyCompany\MyProduct or C:\Program Files (x86)\MyCompany\MyProduct depending on the platform.
       /// </summary>
       public string ProductInstallationFolder
               if (string.IsNullOrEmpty(_productInstallationFolder))
                   var programFilesFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles);
                   _productInstallationFolder = Path.Combine(programFilesFolder, @"MyCompany\MyProduct");
               return _productInstallationFolder;
               _productInstallationFolder = value;
       public void CreateCustomEventLog()
           XmlConfigurator.Configure(new FileInfo(string.Format("{0}.config", this.ProductInstallationFolder))); 
var repository = LogManager.GetRepository() as Hierarchy; if (repository != null) { var appenders = repository.GetAppenders(); if (appenders != null) { foreach (var appender in appenders) { if (appender is EventLogAppender) { var eventLogAppender = appender as EventLogAppender; EventLog.CreateEventSource(eventLogAppender.ApplicationName, eventLogAppender.LogName); // Close application to allow the Windows eventlog service to refresh. // When applcation is restarted the first log event will create the log file. } } } } }