public UninstallerResults Uninstall(Application update)
        {
            var results = new UninstallerResults();

            switch (_winVersion)
            {
            case NTVersion.Server2003:
            case NTVersion.Xp:
                results = WinNT51_52Procedure(update);
                break;

            case NTVersion.VistaServer2008:
                results = WinNT60Procedure(update);
                break;

            case NTVersion.SevenServer2008R2:
                results = WinNT61Procedure(update);
                break;

            case NTVersion.EightServer2012:
                results = WinNT61Procedure(update);
                break;
            }
            return(results);
        }
        private static UninstallerResults ProcessUninstallerResults(WindowsExitCode exitCode)
        {
            UninstallerResults results = new UninstallerResults();

            switch (exitCode)
            {
            ///////////////////// The Good Codes(TM) ///////////////////////////
            case WindowsExitCode.Sucessful:
                results.Success  = true;
                results.Restart  = false;
                results.Message  = "Update was successfully uninstalled.";
                results.ExitCode = WindowsExitCode.Sucessful;
                break;

            case WindowsExitCode.Reboot:
            case WindowsExitCode.Restart:
                results.Success  = true;
                results.Restart  = true;
                results.Message  = "Update was successfully uninstalled, but the system needs to be rebooted.";
                results.ExitCode = WindowsExitCode.Reboot;
                break;
            ///////////////////////////////////////////////////////////////////

            case WindowsExitCode.NotAllowed:
                results.Success  = false;
                results.Restart  = false;
                results.Message  = "Update is required by Windows so it can't be uninstalled.";
                results.ExitCode = WindowsExitCode.NotAllowed;
                break;

            case WindowsExitCode.UpdateNotFound:
                results.Success  = false;
                results.Restart  = false;
                results.Message  = "Update (or installer package) could not be found.";
                results.ExitCode = WindowsExitCode.UpdateNotFound;
                break;

            case WindowsExitCode.Failed:
                results.Success  = false;
                results.Restart  = false;
                results.Message  = "Update could not be uninstalled.";
                results.ExitCode = WindowsExitCode.Failed;
                break;

            case WindowsExitCode.Catastrophic:
                results.Success  = false;
                results.Restart  = false;
                results.Message  = "A catastrophic error accured at the system level.";
                results.ExitCode = WindowsExitCode.Catastrophic;
                break;

            default:
                results.Success  = false;
                results.Restart  = false;
                results.Message  = "Win32 Error: " + new Win32Exception((int)exitCode).Message;
                results.ExitCode = exitCode;
                break;
            }
            return(results);
        }
        /// <summary>
        /// Uninstall updates on Windows 7 & Windows Server 2008 R2. (6.1)
        /// </summary>
        /// <param name="update">Update to uninstall.</param>
        private static UninstallerResults WinNT61Procedure(Application update)
        {
            // TODO: NOT FULLY BAKED!!!! Doesn't check registry for updates that could be there.

            IEnumerable <WindowsUpdates.QfeData> qfeList = WindowsUpdates.QueryWmiHotfixes();
            var temp = new UninstallerResults();

            foreach (WindowsUpdates.QfeData qfe in qfeList)
            {
                try
                {
                    if (qfe.HotFixId.Equals(update.KB))
                    {
                        return(WusaProcess(update.KB));
                    }
                }
                catch (Exception)
                {
                    temp.Message  = "This update does not appear to be Uninstallable. Unable to remove.";
                    temp.Success  = false;
                    temp.Restart  = false;
                    temp.ExitCode = WindowsExitCode.NotAllowed; //TODO: HARDCODED :) MUAHAHAHA. MUST FIX!
                }
            }
            return(temp);
        }
        private void UninstallOperation(RvSofOperation operation)
        {
            var registry = new RegistryReader();
            var tempAppsToAdd = new List<RVsofResult.AppsToAdd2>();
            var tempAppsToDelete = new List<RVsofResult.AppsToDelete2>();
            var savedOperations = Operations.LoadOpDirectory().Where(p => p.operation == OperationValue.Uninstall).ToList();

            if (!savedOperations.Any())
            {
                Logger.Log("There are no operations remaining, Unable to uninstall app: {0}", LogLevel.Warning, operation.Type);
                return;
            }

            foreach (var localOp in savedOperations)
            {
                if (operation.ListOfInstalledApps.Any()) operation.ListOfInstalledApps.Clear();
                if (operation.ListOfAppsAfterInstall.Any()) operation.ListOfAppsAfterInstall.Clear();

                //Retrieve a list of all updates installed in the system before uninstalling anything.
                operation.ListOfInstalledApps = registry.GetRegistryInstalledApplicationNames();
                Operations.UpdateStatus(localOp, Operations.OperationStatus.Processing);

                var msiUninstall = new MSIUninstaller.MSIprop();
                try
                {
                    if (localOp.filedata_app_name != String.Empty)
                        msiUninstall = MSIUninstaller.UnistallApp(localOp.filedata_app_name);
                }
                catch
                {
                    Logger.Log("MSIuninstaller crashed while attempting to uninstall {0}", LogLevel.Error, localOp.filedata_app_name);
                    msiUninstall.UninstallPass = false;
                }

                Application update = null;
                if (!msiUninstall.UninstallPass)
                {
                    var installedUpdates = WindowsUpdates.GetInstalledUpdates();
                    update = (from n in installedUpdates where n.Name == localOp.filedata_app_name select n).FirstOrDefault();
                }

                var uninstallerResults = new UninstallerResults();
                if (!msiUninstall.UninstallPass)
                {
                    try
                    {
                        uninstallerResults = WindowsUninstaller.Uninstall(update);
                    }
                    catch
                    {
                        Logger.Log("Windows Uninstall Update failed.", LogLevel.Error);
                        uninstallerResults.Success = false;
                    }
                }

                //Get all installed application after installing..
                operation.ListOfAppsAfterInstall = registry.GetRegistryInstalledApplicationNames();

                //GET DATA FOR APPSTOADD/APPSTODELETE
                var appListToDelete = RegistryReader.GetAppsToDelete(operation.ListOfInstalledApps, operation.ListOfAppsAfterInstall);
                var appListToAdd    = RegistryReader.GetAppsToAdd(operation.ListOfInstalledApps, operation.ListOfAppsAfterInstall);

                //APPS TO DELETE
                #region Apps to Delete
                if (appListToDelete != null)
                {
                    var temp = registry.GetAllInstalledApplicationDetails();
                    foreach (var app in appListToDelete)
                    {
                        var appsToDelete = new RVsofResult.AppsToDelete2();
                        var version = (from d in temp where d.Name == localOp.filedata_app_name select d.Version).FirstOrDefault();

                        appsToDelete.Name = (String.IsNullOrEmpty(app)) ? String.Empty : app;
                        appsToDelete.Version = (String.IsNullOrEmpty(version)) ? String.Empty : version;

                        tempAppsToDelete.Add(appsToDelete);
                    }
                }
                #endregion

                //APPS TO ADD
                #region Apps to Add
                if (appListToAdd != null)
                {
                    var installedAppsDetails = registry.GetAllInstalledApplicationDetails();

                    foreach (var app in appListToAdd)
                    {
                        var temp = new RVsofResult.AppsToAdd2();
                        var localApp = app;
                        var version = (from d in installedAppsDetails where d.Name == localOp.filedata_app_name select d.Version).FirstOrDefault(); //Default NULL
                        var vendor = (from d in installedAppsDetails where d.Name == localApp select d.VendorName).FirstOrDefault(); //Default NULL
                        var installDate = Tools.ConvertDateToEpoch((from d in installedAppsDetails where d.Name == localApp select d.Date).FirstOrDefault()); //Default 0.0D

                        temp.AppsToAdd.Name = (String.IsNullOrEmpty(localApp)) ? String.Empty : localApp;
                        temp.AppsToAdd.Version = (String.IsNullOrEmpty(version)) ? String.Empty : version;
                        temp.AppsToAdd.InstallDate = (installDate.Equals(0.0D)) ? 0.0D : installDate;
                        temp.AppsToAdd.VendorName = (String.IsNullOrEmpty(vendor)) ? String.Empty : vendor;
                        temp.AppsToAdd.RebootRequired = "no";
                        temp.AppsToAdd.ReleaseDate = 0.0;
                        temp.AppsToAdd.Status = "installed";
                        temp.AppsToAdd.Description = String.Empty;
                        temp.AppsToAdd.SupportUrl = String.Empty;
                        temp.AppsToAdd.VendorId = String.Empty;
                        temp.AppsToAdd.VendorSeverity = String.Empty;
                        temp.AppsToAdd.KB = String.Empty;

                        tempAppsToAdd.Add(temp);
                    }
                }
                #endregion

                if (uninstallerResults.Success || msiUninstall.UninstallPass)
                {
                    // Success! Uinstalled OK
                    localOp.success = true.ToString().ToLower();
                    localOp.reboot_required = String.IsNullOrEmpty(uninstallerResults.Restart.ToString()) ? "no" : uninstallerResults.Restart.ToString();
                    localOp.error = string.Empty;

                    operation.Api = ApiCalls.RvUninstallOperation();
                    operation.Type = OperationValue.Uninstall;
                    operation.Id = localOp.operation_id;

                    InstallSendResults(localOp, operation, tempAppsToAdd, tempAppsToDelete);
                }
                else
                {
                    // Fail! Uinstalled Failed.
                    localOp.success = false.ToString().ToLower();
                    localOp.reboot_required = String.IsNullOrEmpty(uninstallerResults.Restart.ToString()) ? "no" : uninstallerResults.Restart.ToString();
                    localOp.error = "Unable to successfully uninstall application. If this is not a Windows Update Uninstall, ensure that the application is of type MSI We currently do not support other installers. Error: " + msiUninstall.Error;

                    operation.Api = ApiCalls.RvUninstallOperation();
                    operation.Type = OperationValue.Uninstall;
                    operation.Id = localOp.operation_id;

                    InstallSendResults(localOp, operation, tempAppsToAdd, tempAppsToDelete);
                }
            }
        }
 public UninstallerResults Uninstall(Application update)
 {
     var results = new UninstallerResults();
     switch (_winVersion)
     {
         case NTVersion.Server2003:
         case NTVersion.Xp:
             results = WinNT51_52Procedure(update);
             break;
         case NTVersion.VistaServer2008:
             results = WinNT60Procedure(update);
             break;
         case NTVersion.SevenServer2008R2:
             results = WinNT61Procedure(update);
             break;
         case NTVersion.EightServer2012:
             results = WinNT61Procedure(update);
             break;
     }
     return results;
 }
        /// <summary>
        /// Uninstall updates on Windows 7 & Windows Server 2008 R2. (6.1)
        /// </summary>
        /// <param name="update">Update to uninstall.</param>
        private static UninstallerResults WinNT61Procedure(Application update)
        {
            // TODO: NOT FULLY BAKED!!!! Doesn't check registry for updates that could be there.

            IEnumerable<WindowsUpdates.QfeData> qfeList = WindowsUpdates.QueryWmiHotfixes();
            var temp = new UninstallerResults();

            foreach (WindowsUpdates.QfeData qfe in qfeList)
            {
                try
                {
                    if (qfe.HotFixId.Equals(update.KB))
                    {
                        return WusaProcess(update.KB);
                    }
                }
                catch (Exception)
                {
                  temp.Message = "This update does not appear to be Uninstallable. Unable to remove.";
                  temp.Success = false;
                  temp.Restart = false;
                  temp.ExitCode = WindowsExitCode.NotAllowed;  //TODO: HARDCODED :) MUAHAHAHA. MUST FIX!
                }
            }
            return temp;
        }
        private static UninstallerResults ProcessUninstallerResults(WindowsExitCode exitCode)
        {
            UninstallerResults results = new UninstallerResults();

            switch (exitCode)
            {
                ///////////////////// The Good Codes(TM) ///////////////////////////
                case WindowsExitCode.Sucessful:
                    results.Success = true;
                    results.Restart = false;
                    results.Message = "Update was successfully uninstalled.";
                    results.ExitCode = WindowsExitCode.Sucessful;
                    break;

                case WindowsExitCode.Reboot:
                case WindowsExitCode.Restart:
                    results.Success = true;
                    results.Restart = true;
                    results.Message = "Update was successfully uninstalled, but the system needs to be rebooted.";
                    results.ExitCode = WindowsExitCode.Reboot;
                    break;
                ///////////////////////////////////////////////////////////////////

                case WindowsExitCode.NotAllowed:
                    results.Success = false;
                    results.Restart = false;
                    results.Message = "Update is required by Windows so it can't be uninstalled.";
                    results.ExitCode = WindowsExitCode.NotAllowed;
                    break;

                case WindowsExitCode.UpdateNotFound:
                    results.Success = false;
                    results.Restart = false;
                    results.Message = "Update (or installer package) could not be found.";
                    results.ExitCode = WindowsExitCode.UpdateNotFound;
                    break;

                case WindowsExitCode.Failed:
                    results.Success = false;
                    results.Restart = false;
                    results.Message = "Update could not be uninstalled.";
                    results.ExitCode = WindowsExitCode.Failed;
                    break;

                case WindowsExitCode.Catastrophic:
                    results.Success = false;
                    results.Restart = false;
                    results.Message = "A catastrophic error accured at the system level.";
                    results.ExitCode = WindowsExitCode.Catastrophic;
                    break;

                default:
                    results.Success = false;
                    results.Restart = false;
                    results.Message = "Win32 Error: " + new Win32Exception((int)exitCode).Message;
                    results.ExitCode = exitCode;
                    break;
            }
            return results;
        }