locked
How to stop or cancel installation in Installer class? in .net 2005 RRS feed

  • Question

  • I am creating a windows setup file in .net 2005 framework 2.0
    I am using installer class to control the installation as custom Action, while installing i do onlie verification getting  username and password,
    Now the thing is if the verification fails the installation should be cancelled?
    How do i implement this in custom action from installer class.
    Tuesday, March 11, 2008 10:48 AM

All replies

  • Hi,

    You should try to override Rollback method of Installer class, and call it when installation should be canceled.
    Tuesday, March 11, 2008 1:14 PM
  • If i called the Rollback method i am getting the following error message.

    The savedState dictionary does not contain the expected values and might have been corrupted.

    and

    An exception occurred during the Rollback phase of the installation. This exception will be ignored and the rollback will continue.However,the machine might not fully revert to its initial state after the rollback is complete.--> The savedState dictionary does not contain the expected values and might have been corrupted.

    what value to assign the savedState?

    Wednesday, March 12, 2008 7:28 AM
  •  

    Hi Mohan.K,

    Based on my understanding, you want to cancel the installation if the verification custom action failed, don’t you? If so, you can throw an exception when the verification custom action fails, and it will force the installation roll back and the installation will get canceled. Try something like the following:

    Code Snippet

            protected override void OnBeforeInstall(System.Collections.IDictionary savedState)

            {

                //your verification code here

                if (verification fails)

                    throw new Exception("verification failed!");

                base.OnBeforeInstall(savedState);

            }

     

    Hope this helps.
    Best regards.
    Rong-Chun Zhang

    Monday, March 17, 2008 6:49 AM
  •  

    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

    Tuesday, May 6, 2008 2:40 PM
  • I believe a preferable exception to throw is an InstallException.

     

    Tuesday, May 6, 2008 5:49 PM
  • yes but, but the Cancel_button is on forms, these forms are the models of Installer Project, so i can't see the code of the button.

    How can i know the user is clicking on Cancel_Button? which Event?

     

    Wednesday, May 7, 2008 7:32 AM
  • Hi,

    The Cancel button code is hidden from the user and you cannot alter the code.
    Microsoft is somewhat rigid in this regard.

    Regards,
    Dileep
    Wednesday, May 7, 2008 12:17 PM
  •  Rong-Chun Zhang - MSFT wrote:

     

    Hi Mohan.K,

    Based on my understanding, you want to cancel the installation if the verification custom action failed, don’t you? If so, you can throw an exception when the verification custom action fails, and it will force the installation roll back and the installation will get canceled. Try something like the following:

    Code Snippet

            protected override void OnBeforeInstall(System.Collections.IDictionary savedState)

            {

                //your verification code here

                if (verification fails)

                    throw new Exception("verification failed!");

                base.OnBeforeInstall(savedState);

            }

     

    Hope this helps.
    Best regards.
    Rong-Chun Zhang

     

    Thanks.  Tested this and it works fine, but I don't like the Exception thing in there.  In fact it's not an exception. 

     

    In my code, we don't support certain versions of Windows.  We alert the User of his version and ask him if he still wants to install the application.  The user clicked No.  I feel like throwing an exception in the middle of a normal process.  I DO want to roolback the installation.

     

    Has anyone used the Rollback with success?

    • Proposed as answer by manjuby Tuesday, January 29, 2013 12:34 PM
    Wednesday, May 7, 2008 12:45 PM
  •  

    so there is no way to know if the user wants to cancel install? even with other dll?

    Can I add some forms, which i have made, to the Installer Project?

    Wednesday, May 7, 2008 3:26 PM
  • Geof75, the user can hit the cancel button that's shown during the install and the installation will stop and rollback, to leave the system in the state it was before. There are Cance buttons in the UI when the user runs the install. So I know your English isn't too good, but it's not clear what you're asking, because the user can cancel the install and it works, and if you have installer class code then you can throw an InstallException if your code decides that it needs to stop the install.

     

    Wednesday, May 7, 2008 9:24 PM
  •  PhilWilson wrote:

    Geof75, the user can hit the cancel button that's shown during the install and the installation will stop and rollback, to leave the system in the state it was before. There are Cance buttons in the UI when the user runs the install. So I know your English isn't too good, but it's not clear what you're asking, because the user can cancel the install and it works, and if you have installer class code then you can throw an InstallException if your code decides that it needs to stop the install.

     

     

    The problem (it's not a big one in fact) is that we don't support all versions of Windows, Office etc.. We just want to popup what versions are on the PC and offer the user if he wants to continue or not.

     

    The Exception works fine.  We just thought why not use the Rollback... but that thing doesn't seem to work.

     

    Thanks

    Thursday, May 8, 2008 12:40 PM
  •  PhilWilson wrote:

    Geof75, the user can hit the cancel button that's shown during the install and the installation will stop and rollback, to leave the system in the state it was before. There are Cance buttons in the UI when the user runs the install. So I know your English isn't too good, but it's not clear what you're asking, because the user can cancel the install and it works, and if you have installer class code then you can throw an InstallException if your code decides that it needs to stop the install.

     

     

    With my installer class when I want to cancel Installation, it doesn't work.

    How can I throw an InstallException? cause I don't know when the user hits the cancel button...

    Tuesday, May 13, 2008 7:43 AM
  • Rong-Chun Zhang - MSFT wrote it

     

    protected override void OnBeforeInstall(System.Collections.IDictionary savedState)

            {

                //your verification code here

                if (verification fails)

                    throw new Exception("verification failed!");

                base.OnBeforeInstall(savedState);

            }

     

    I replaced the if (verification fails ) by a message box with a yes no message.  Then you just throw the excteption.  Since there is an exception (the one you throw) during installation, the installer will rollback all it has done.

     

    It works .

    Wednesday, May 14, 2008 3:19 PM
  • People typically block installation on unsupported Windows versions by using a launch condition with a test of the VersionNT property. This prevents the install.  If you were using another setup tool you'd add a custom action in the UI sequence conditioned on the versions of Windows (or Office etc) and prompt the user for an ok to continue. This could prevent anything being installed on the system at all. But you're in a situation where you can only do this in a custom action which is called AFTER everything has been installed. This leaves you no choice but to throw an InstallException. It's a weird situation though. It would be very unusual if Visual Studio installed this way, rolling back after everything has been installed. It's a case where your setup tool doesn't provide the kind of functionality that would normally be used.

     

    Use of the Cancel button can be detected (sort of) in a Rollback custom action because a rollback custom action will be called by Windows as the install rolls back after being canceled (or failing).

     

    Wednesday, May 14, 2008 5:19 PM
  • Try this code in your installer class. I hope it will resolve your problem.


    protected override void OnBeforeInstall(IDictionary savedState)
            {
                if (LaunchOnBeforeInstall())
                {
                    base.OnBeforeInstall(savedState);
                }
                else
                {
                    throw new Exception("You cancelled installation");
                }
            }
            public bool LaunchOnBeforeInstall()
            {
                Form2 frm2 = new Form2();
                DialogResult result = frm2.ShowDialog();
                if (result == DialogResult.Cancel)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
    Monday, March 1, 2010 6:00 AM
  • It really should be a new InstallException.
    Phil Wilson
    Wednesday, March 3, 2010 12:26 AM
  • I am creating a windows setup file in .net 2005 framework 2.0
    I am using installer class to control the installation as custom Action, while installing i do onlie verification getting  username and password,
    Now the thing is if the verification fails the installation should be cancelled?
    How do i implement this in custom action from installer class.

    Although the OP likely will not be able to benefit from this post, this article comes up in Google rankings high for the error he received when calling the Rollback method manually.

    You can throw a new Exception or InstallException, but this creates an unsightly error message which you would not want your users to see.

    An alternative would be to click/call the cancel button for the base installer from your custom action code.

    To work around this, simply import User32.dll and call the "SendMessage" function, passing in the handle of cancel button. See code example below:

     [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
    
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SetActiveWindow(IntPtr hWnd);
    
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
    
        enum ShowWindowCommands : int
        {
    
          Hide = 0,
          Normal = 1,
          ShowMinimized = 2,
          Maximize = 3,  
          ShowMaximized = 3,
          ShowNoActivate = 4,
          Show = 5,
          Minimize = 6,
          ShowMinNoActive = 7,
          ShowNA = 8,
          Restore = 9,
          ShowDefault = 10,
          ForceMinimize = 11
        }
    
    public static string InstallTitle = "AppbarTitle"; //used to get the window handle
    
     public override void Install(System.Collections.IDictionary stateSaver)
        {
    ShowWindow(msiwindowhandle, ShowWindowCommands.Show);
            IntPtr cancelbuttonhandle;
            const int BM_CLICK = 0x00F5;
            msiwindowhandle = FindWindow("#32770", InstallTitle);
            cancelbuttonhandle = FindWindowEx(msiwindowhandle, IntPtr.Zero, "Button", "Cancel");
            SetActiveWindow(msiwindowhandle); //necessary for button click to fire
            SendMessage(cancelbuttonhandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
    }
    

    • Proposed as answer by Ronnie.Diaz Monday, June 20, 2011 8:01 PM
    Monday, June 20, 2011 8:00 PM
  • That is a great fix..It really works.
    I have forgot to mention one thing....like the code to handle the cancel button has to be placed in OnBeforeInstall(IDictionary stateSaver) method instead of using it in Install(IDictionary stateSaver) method as above. Also pass the msiwindowhandle as IntPtr.Zero in the ShowWindow(msiwindowhandle, ShowWindowCommands.Show); method...

    And It works undoubtedly.

    Thank you once again.


    Wednesday, October 31, 2012 2:40 PM
  • Hi 

    Thank u very much,

    This was what  I was looking for

    but i am not able to call this function wherever i need..I want to abort setup wizard on certain conditions..how to call this functions..on that condition

    plz guide.

    Tuesday, January 29, 2013 12:36 PM
  • If the only thing all you people are worried about is the format of the error message then open the MSI file with Orca and just change it in the Error table.  There's no need for all these gymnastics.

    If the user hits the Cancel button during the install (not in the UI, in the progress section) then the install will stop and roll back. . You can of course add Rollback custom action that will be called during a Rollback if your custom action has been called, but anyway Cancel just undoes the install.


    Phil Wilson

    Tuesday, January 29, 2013 7:30 PM
  • nice post but like to know can't we stop installation without throwing exception?
    Monday, April 6, 2015 2:05 PM
  • You need to define what your "stop" actually means.

    For example, it might mean "prevent from launching".  The user can do a Cancel at multiple places, including in the UI at the start and when the install is actually happening, so that's probably not the issue. Otherwise you can't just stop the installation any more than you can stop Explorer copying files from one place to another.  So the only place you can stop the installation is at places where your code runs. In VS setups, that place is a custom action, and in VS they all run at the end when the install is virtually complete and all the files have been copied. So you throw a new InstallException and it rolls back. And that applies to the code example above that presses the Cancel buton too! In a VS custom action that runs when the install is virtually complete you still cause a rollback. It's also a lie, giving everyone else the illusion that the user pressed the Cancel button, and that did not happen, and yes there are times when arguments occur over why the install was canceled and when it appears that the user pressed Cancel and did not. So leave the darn buttons for users.  So the issue is really what the use case or scenario where you want to stop the installation.


    Phil Wilson



    • Edited by PhilWilson Tuesday, April 7, 2015 5:25 PM Typos
    Tuesday, April 7, 2015 5:21 PM
  • Simple question: Can I cancel installation from a custom action that is implemented with .net installer class?

    The simple answer is yes: throw an InstallException.

    Yeah, BUT!!!!

    That exposes the user to an ugly exception message. Worse yet, this message is a Microsoft bug. It incorrectly states that install will continue instead of what it really does, which is initiate rollback.

    Any other way to do it?

    I suspect that the only way to do it cleanly is to implement the custom action in a way that allows you to return 1602 (ERROR_INSTALL_USEREXIT). (for example exe or unmannaged C++ dll)

    Just admit when there's a limitation of the system, instead of asking questions like what "stop" means.



    Monday, July 16, 2018 3:31 PM