Click here to Skip to main content
15,895,011 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 254.3K   9.8K   235  
Extending Visual Studio Setup Project for Building Reliable Windows Installer (MSI)
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using System.IO;

namespace SetupHelper
{
    [RunInstaller(true)]
    public partial class MyInstallerHelper : Installer
    {
        public MyInstallerHelper()
        {
            InitializeComponent();
        }

        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
        }

        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);
        }

        protected override void OnAfterInstall(IDictionary savedState)
        {
            base.OnAfterInstall(savedState);
        }

        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
        }

        protected override void OnAfterRollback(IDictionary savedState)
        {
            base.OnAfterRollback(savedState);
        }

        protected override void OnAfterUninstall(IDictionary savedState)
        {
            base.OnAfterUninstall(savedState);
        }

        protected override void OnBeforeRollback(IDictionary savedState)
        {
            base.OnBeforeRollback(savedState);
        }

        protected override void OnBeforeUninstall(IDictionary savedState)
        {
            base.OnBeforeUninstall(savedState);
        }

        protected override void OnCommitted(IDictionary savedState)
        {
            base.OnCommitted(savedState);
        }

        protected override void OnCommitting(IDictionary savedState)
        {
            base.OnCommitting(savedState);
        }

        public override void Uninstall(IDictionary savedState)
        {
            base.Uninstall(savedState);
        }

        protected override void OnBeforeInstall(IDictionary savedState)
        {
            try
            {
                base.OnBeforeInstall(savedState);
                FileInfo fileInfo = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
                //Take custom action data values
                string sProgram = Context.Parameters["Run"];
                sProgram = Path.Combine(fileInfo.DirectoryName, sProgram);
                Trace.WriteLine("Install sProgram= " + sProgram);
                OpenWithStartInfo(sProgram);
            }
            catch (Exception exc)
            {
                Context.LogMessage(exc.ToString());
                throw;
            }
        }

        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 
            SetForegroundWindow(p.MainWindowHandle);
            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.
            }
        }

        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(" /");
            sb.Append(Key);
            //Note that if value is empty string, = sign is expected, e.g."/PORT="
            if (value != null)
            {
                sb.Append("=");
                sb.Append(value);
            }
            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"

        // http://pinvoke.net/default.aspx/user32.BringWindowToTop
        [DllImport("user32.dll")]
        static extern bool BringWindowToTop(IntPtr hWnd);

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

        //from http://pinvoke.net/default.aspx/user32.SwitchToThisWindow 
        [DllImport("user32.dll")]
        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
        {
            /// <summary>Hides the window and activates another window.</summary>
            /// <remarks>See SW_HIDE</remarks>
            Hide = 0,
            /// <summary>Activates and displays a window. If the window is minimized 
            /// or maximized, the system restores it to its original size and 
            /// position. An application should specify this flag when displaying 
            /// the window for the first time.</summary>
            /// <remarks>See SW_SHOWNORMAL</remarks>
            ShowNormal = 1,
            /// <summary>Activates the window and displays it as a minimized window.</summary>
            /// <remarks>See SW_SHOWMINIMIZED</remarks>
            ShowMinimized = 2,
            /// <summary>Activates the window and displays it as a maximized window.</summary>
            /// <remarks>See SW_SHOWMAXIMIZED</remarks>
            ShowMaximized = 3,
            /// <summary>Maximizes the specified window.</summary>
            /// <remarks>See SW_MAXIMIZE</remarks>
            Maximize = 3,
            /// <summary>Displays a window in its most recent size and position. 
            /// This value is similar to "ShowNormal", except the window is not 
            /// actived.</summary>
            /// <remarks>See SW_SHOWNOACTIVATE</remarks>
            ShowNormalNoActivate = 4,
            /// <summary>Activates the window and displays it in its current size 
            /// and position.</summary>
            /// <remarks>See SW_SHOW</remarks>
            Show = 5,
            /// <summary>Minimizes the specified window and activates the next 
            /// top-level window in the Z order.</summary>
            /// <remarks>See SW_MINIMIZE</remarks>
            Minimize = 6,
            /// <summary>Displays the window as a minimized window. This value is 
            /// similar to "ShowMinimized", except the window is not activated.</summary>
            /// <remarks>See SW_SHOWMINNOACTIVE</remarks>
            ShowMinNoActivate = 7,
            /// <summary>Displays the window in its current size and position. This 
            /// value is similar to "Show", except the window is not activated.</summary>
            /// <remarks>See SW_SHOWNA</remarks>
            ShowNoActivate = 8,
            /// <summary>Activates and displays the window. If the window is 
            /// minimized or maximized, the system restores it to its original size 
            /// and position. An application should specify this flag when restoring 
            /// a minimized window.</summary>
            /// <remarks>See SW_RESTORE</remarks>
            Restore = 9,
            /// <summary>Sets the show state based on the SW_ value specified in the 
            /// STARTUPINFO structure passed to the CreateProcess function by the 
            /// program that started the application.</summary>
            /// <remarks>See SW_SHOWDEFAULT</remarks>
            ShowDefault = 10,
            /// <summary>Windows 2000/XP: Minimizes a window, even if the thread 
            /// that owns the window is hung. This flag should only be used when 
            /// minimizing windows from a different thread.</summary>
            /// <remarks>See SW_FORCEMINIMIZE</remarks>
            ForceMinimized = 11
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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: http://blogs.microsoft.co.il/blogs/shair/

Comments and Discussions