コード例 #1
0
        /// <summary>
        /// Do the actual leg-work of removing a package. Optionally make it
        /// a forceful removal (used during a failed system install, or possibly
        /// a future system un-install). A forceful removal means that dependency
        /// checks are ignored and an error while deleting the database record
        /// is ignored (since the table may no longer exist).
        /// </summary>
        /// <param name="packageName">The name of the package to remove.</param>
        /// <param name="forceRemove">Wether or not to force the removal.</param>
        private void RemovePackage(String packageName, Boolean forceRemove)
        {
            PackageInstaller installer = new PackageInstaller(this);
            Database         db;
            Package          package;
            Migration        mig;
            Boolean          LocalTransaction = false;


            //
            // Check if the package is installed.
            //
            package = GetInstalledPackage(packageName);
            if (package == null)
            {
                throw new PackageNotInstalledException(String.Format("The package {0} is not currently installed.", packageName));
            }

            //
            // Check if there are any packages that depend on the package
            // we are about to remove.
            //
            if (forceRemove == false)
            {
                if (PackagesRequiring(packageName).Count > 0)
                {
                    throw new PackageDependencyException(String.Format("The package {0} as dependencies and cannot be removed.", packageName));
                }
            }

            //
            // Begin the SQL Transaction.
            //
            if (Command.Transaction == null)
            {
                Command.Transaction = Connection.BeginTransaction();
                LocalTransaction    = true;
            }
            db = new Database(Command);


            //
            // Begin the actual removal process.
            //
            try
            {
                //
                // Unconfigure all packages that recommend this one.
                //
                try
                {
                    foreach (String name in PackagesRecommending(packageName))
                    {
                        mig = installer.MigrationForPackage(GetInstalledPackage(name));
                        if (mig != null)
                        {
                            mig.Unconfigure(db, null, packageName);
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new DatabaseMigrationException("Unable to re-configure dependent packages.", e);
                }

                //
                // Unconfigure this package.
                //
                try
                {
                    //
                    // Load the migration object from the package.
                    //
                    mig = installer.MigrationForPackage(package);

                    if (mig != null)
                    {
                        //
                        // Unconfigure this package from its recommendations.
                        //
                        foreach (PackageRecommendation pkg in package.Info.Recommends)
                        {
                            mig.Unconfigure(db, null, pkg.Name);
                        }

                        //
                        // Unconfigure this package from its requirements.
                        //
                        foreach (PackageRequirement pkg in package.Info.Requires)
                        {
                            mig.Unconfigure(db, null, pkg.Name);
                        }

                        //
                        // Do a general unconfigure of this package.
                        //
                        mig.Unconfigure(db, null, null);
                    }
                }
                catch (Exception e)
                {
                    throw new DatabaseMigrationException("Unable to unconfigure package.", e);
                }

                //
                // Remove all the new files, pages, modules, etc.
                //
                try
                {
                    installer.RemovePackagePages(package);
                    installer.RemovePackageModules(package);
                    installer.RemovePackageFiles(package);
                }
                catch (IOException) { throw; }
                catch (Exception) { throw; }

                //
                // Migrate the database to a completely non-existant state.
                //
                if (mig != null)
                {
                    try
                    {
                        mig.Downgrade(db, null);
                    }
                    catch (Exception e)
                    {
                        throw new DatabaseMigrationException("Error while trying to migrate database.", e);
                    }
                }

                //
                // Remove the package from the database.
                //
                try
                {
                    Command.CommandType = CommandType.Text;
                    Command.CommandText = "DELETE FROM [cust_rc_packager_packages] WHERE [name] = @Name";
                    Command.Parameters.Clear();
                    Command.Parameters.Add(new SqlParameter("@Name", package.Info.PackageName));
                    Command.ExecuteNonQuery();
                }
                catch
                {
                    if (forceRemove == false)
                    {
                        throw;
                    }
                }

                //
                // Commit database changes, we are all done.
                //
                if (LocalTransaction)
                {
                    Command.Transaction.Commit();
                    Command.Transaction    = null;
                    db.Command.Transaction = null;
                }
            }
            catch (Exception)
            {
                //
                // Rollback file system changes.
                //
                try
                {
                    installer.RevertFileChanges();
                }
                catch { }

                //
                // Rollback database changes.
                //
                if (LocalTransaction)
                {
                    Command.Transaction.Rollback();
                    Command.Transaction    = null;
                    db.Command.Transaction = null;
                }

                //
                // Throw the exception again.
                //
                throw;
            }
        }