Ejemplo n.º 1
0
        public void Execute(PackageExecutionSettings settings)
        {
            ///////////////////////////////////
            // Prepare

            EnsureState();

            if (IsBusy)
            {
                throw new InvalidOperationException("Cannot execute another package whilst executing a package.");
            }
            IsBusy = true;

            if (settings.LiteMode)
            {
                FactoryOptions.Populate();
                FactoryOptions.Instance[Anolis.Core.Data.DirectoryResourceDataFactory.IconSizeLimit] = 128;
            }

            ///////////////////////////////////
            // Create Backup Details

            Group backupGroup = null;

            if (settings.BackupDirectory != null)
            {
                if (settings.BackupDirectory.Exists)
                {
                    settings.BackupDirectory = new DirectoryInfo(PackageUtility.GetUnusedDirectoryName(settings.BackupDirectory.FullName));
                }

                settings.BackupDirectory.Create();
                settings.BackupDirectory.Refresh();

                Package backupPackage = new Package(settings.BackupDirectory);
                backupPackage.Version     = this.Version;
                backupPackage.Name        = this.Name + " Uninstallation Package";
                backupPackage.Attribution = "Anolis Installer";
                backupPackage.FeedbackUri = this.FeedbackUri;

                backupGroup = backupPackage.RootGroup;
            }

            ExecutionInfo = new PackageExecutionSettingsInfo(this, settings.ExecutionMode, settings.CreateSystemRestorePoint, settings.LiteMode, backupGroup, settings.I386Directory);

            ///////////////////////////////////
            // Flatten

            Log.Add(LogSeverity.Info, "Beginning package execution: " + this.Name + ", with mode " + ExecutionInfo.ExecutionMode.ToString());

            OnProgressEvent(new PackageProgressEventArgs(0, "Flattening Package Tree"));

            List <Operation> operations = new List <Operation>();

            RootGroup.Flatten(operations);

            List <Operation> obsoleteOperations = new List <Operation>();

            Dictionary <String, Operation> uniques = new Dictionary <String, Operation>();

            foreach (Operation op in operations)
            {
                if (!op.IsEnabled)
                {
                    obsoleteOperations.Add(op);
                    continue;
                }

                Operation originalOperation;
                if (uniques.TryGetValue(op.Key, out originalOperation))
                {
                    if (originalOperation.Merge(op))
                    {
                        obsoleteOperations.Add(op);
                    }
                }
                else
                {
                    uniques.Add(op.Key, op);
                }
            }

            operations.RemoveAll(op => obsoleteOperations.Contains(op));

            ///////////////////////////////////
            // Prepare

            if (ExecutionInfo.ExecutionMode == PackageExecutionMode.Regular)
            {
                PackageUtility.AllowProtectedRenames();
            }

            Int64 restorePointSequenceNumber = -2;

            ///////////////////////////////////
            // System Restore, Part 1
            if (ExecutionInfo.ExecutionMode == PackageExecutionMode.Regular && ExecutionInfo.CreateSystemRestorePoint)
            {
                if (SystemRestore.IsSystemRestoreAvailable())
                {
                    OnProgressEvent(new PackageProgressEventArgs(-1, "Creating System Restore Point"));

                    String pointName = "Installed Anolis Package \"" + this.Name + '"';

                    restorePointSequenceNumber = SystemRestore.CreateRestorePoint(pointName, SystemRestoreType.ApplicationInstall);

                    if (restorePointSequenceNumber < 0)
                    {
                        Log.Add(LogSeverity.Error, "Failed to create System Restore point");
                    }
                }
                else
                {
                    Log.Add(LogSeverity.Error, "System Restore not supported");
                }
            }

            ///////////////////////////////////
            // Install (Backup and Execute; backups are the responisiblity of each Operation)

            try {
                float i = 0, cnt = operations.Count;

                foreach (Operation op in operations)
                {
                    OnProgressEvent(new PackageProgressEventArgs((int)(100 * i++ / cnt), op.ToString()));

                    if (!op.SupportsCDImage && ExecutionInfo.ExecutionMode == PackageExecutionMode.CDImage)
                    {
                        continue;
                    }

                    try {
                        if (op.CustomEvaluation)
                        {
                            op.Execute();
                        }
                        else
                        {
                            EvaluationResult result = op.Evaluate();

                            switch (result)
                            {
                            case EvaluationResult.False:
                                Log.Add(LogSeverity.Info, "Evaluation False - " + op.Key);
                                break;

                            case EvaluationResult.FalseParent:
                                Log.Add(LogSeverity.Info, "Evaluation ParentFalse - " + op.Key);
                                break;

                            case EvaluationResult.Error:
                                Log.Add(LogSeverity.Error, "Evaluation Error - " + op.Key);
                                break;

                            case EvaluationResult.True:
                                op.Execute();
                                break;
                            }
                        }
                    } catch (Exception ex) {
                        Log.Add(new LogItem(LogSeverity.Error, ex, op.Name + " failed: \"" + ex.Message + "\""));
                        continue;
                    }

#if !DEBUG
                    // don't add "Info - Done {op}" in debug mode because it's too verbose and clutters up the logfile
                    PathOperation pathOp = op as PathOperation;
                    if (pathOp != null)
                    {
                        Log.Add(LogSeverity.Info, "Done " + op.Name + ": " + pathOp.Path);
                    }
                    else
                    {
                        Log.Add(LogSeverity.Info, "Done " + op.Name);
                    }
#endif
                }                //foreach

                OnProgressEvent(new PackageProgressEventArgs(100, "Complete"));
            } finally {
                ///////////////////////////////////
                // System Restore, Part 2
                if (restorePointSequenceNumber >= 0)
                {
                    OnProgressEvent(new PackageProgressEventArgs(-1, "Finishing System Restore Point"));

                    SystemRestore.EndRestorePoint(restorePointSequenceNumber);
                }

                ///////////////////////////////////
                // Backup, Part 2

                if (ExecutionInfo.BackupGroup != null)
                {
                    String backupFileName = Path.Combine(ExecutionInfo.BackupDirectory.FullName, "Package.xml");

                    ExecutionInfo.BackupPackage.Write(backupFileName);
                }

                ///////////////////////////////////
                // Dump the log to disk

                Log.Save(Path.Combine(this.RootDirectory.FullName, "Anolis.Installer.log"));

                IsBusy = false;
            }            //try/finally
        }