?
Solved

Custom actions and rolling back installation on error

Posted on 2012-04-12
7
Medium Priority
?
385 Views
Last Modified: 2012-04-13
I have a Setup project and I added installer class to it that performs couple of actions via custom functions I can from Install procedure in my Install class I added to custom actions.

I need help writing Rollback procedure to reverse installation in case on an error. Can someone help by pointing me in the right direction?
0
Comment
Question by:YZlat
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 2
7 Comments
 
LVL 40
ID: 37838523
Override the Rollback method in your class, and undo there any operation that was done by the installer, using a lot of checks and Try...Catch. If the installation creates a file for instance, make sure that it exists before trying to delete it in the Rollback method.
0
 
LVL 35

Author Comment

by:YZlat
ID: 37839042
How would I activate the Rollback method in case of an error?
0
 
LVL 40

Accepted Solution

by:
Jacques Bourgeois (James Burger) earned 1500 total points
ID: 37839311
Simply throw an InstallException.
0
Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

 
LVL 35

Author Comment

by:YZlat
ID: 37839783
Thanks, I will try that
0
 
LVL 35

Author Comment

by:YZlat
ID: 37843979
I added custom action for the rollback and then the following code to my Installer class but when an error occurs during installation, it does not rollback nor enters error handler in Install procedure.
Here is my code:

 public void CreateRebootSchedTask()
        {
            try
            {
                // Get the service on the local machine
                using (TaskService ts = new TaskService())
                {
                    // Create a new task definition and assign properties
                    TaskDefinition td = ts.NewTask();

                    td.RegistrationInfo.Description = "Schedules Reboot Service";

                    // Create a trigger that will fire the task at this time every other day
                    TimeTrigger tt = new TimeTrigger();

                    tt.Enabled = true;
                    tt.StartBoundary = DateTime.Now + TimeSpan.FromMinutes(5);
                    tt.Repetition.Interval = TimeSpan.FromHours(1);
                    MessageBox.Show("OS Version = " + Environment.OSVersion.Version.Major.ToString());
                    if (Environment.OSVersion.Version.Major < 6)
                    {
                        tt.Repetition.Duration = TimeSpan.FromDays(365);
                    }
                    td.Triggers.Add(tt);

                    td.Principal.LogonType = TaskLogonType.InteractiveToken;
                    td.Principal.UserId = "NT AUTHORITY\\SYSTEM";
                   // if (Environment.OSVersion.Version.Major > 6)
                   // { error will occur here
                        td.Principal.RunLevel = TaskRunLevel.Highest;
                   // }

                    // Create an action that will launch RebootTimerService whenever the trigger fires
                    td.Actions.Add(new ExecAction("MyReboot.exe", null, Environment.GetEnvironmentVariable("windir")));

                    // Register the task in the root folder
                    ts.RootFolder.RegisterTaskDefinition(taskName, td, TaskCreation.Create, "SYSTEM", null, TaskLogonType.ServiceAccount, null);
                }
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("MyLog", "Error during installation in task creation: " + ex.Message + " - " + ex.StackTrace);
                throw new InstallException("Error during installation.", ex);
            }

        }

public override void Install(IDictionary stateSaver) 
        { 
            
            
            try
            {
                base.Install(stateSaver);
                
                CreateRebootSchedTask();
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("MyLog", "Error during installation: " + ex.Message + " - " + ex.StackTrace);
                throw new InstallException("Error during installation.",ex);
            }
        }

       

        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
            EventLog.WriteEntry("MyLog", "Rollback...");

            try
            {
                DeleteScheduledTask(taskName);
                RemoveDataFromDB(taskName);
            }
            catch (IOException ioex)
            {
                EventLog.WriteEntry("MyLog", "Scheduled task does not exist so it cannot be deleted: " + ioex.Message);
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("MyLog", "Error during rollback: " + ex.Message + " - " + ex.StackTrace);
            }

        }

Open in new window

0
 
LVL 35

Author Comment

by:YZlat
ID: 37844330
Figured it out! Thanks!
0
 
LVL 35

Author Closing Comment

by:YZlat
ID: 37844334
Thanks!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question