/// <summary> /// Deserialize settings from file /// </summary> /// <param name="xmlFilePath"> full qualified path to file</param> /// <returns></returns> public static HotfixSettings load(string xmlFilePath) { //deserialize from file XmlSerializer serializer = new XmlSerializer(typeof(HotfixSettings)); TextReader tr = new StreamReader(xmlFilePath); HotfixSettings inst = serializer.Deserialize(tr) as HotfixSettings; inst.mstrSettingsFileName = xmlFilePath; tr.Close(); return(inst); }
public HotfixBackup(HotfixSettings settings, Logger log, ArrayList processed) { this.settings = settings; this.log = log; this.processed = processed; //---------------------------------------------------------------------------- // folder of all backups //---------------------------------------------------------------------------- if (settings.Backup.blnIsRelative) { strBackupFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, settings.Backup.strFolder); } else { strBackupFolder = settings.Backup.strFolder; } }
/// <summary> /// Initializes service processor instance by only those services /// that installed on processed machine and appeared in settings of hotfix /// </summary> /// <param name="settings">Settings object of hotfix</param> /// <param name="log">Logger object</param> public ServiceProcessor(HotfixSettings settings, Logger log) { this.settings = settings; this.log = log; //------------------------------------------------------- // Get list of installed services // TODO: remote access //------------------------------------------------------- ServiceController[] existingServices = ServiceController.GetServices(); //------------------------------------------------------- // Sort array in ascending order to be able to use binary search //------------------------------------------------------- Array.Sort(existingServices, 0, existingServices.Length, new ServiceComparer()); foreach (HotfixSettings.Service service in this.settings.Services) { int index = -1; index = Array.BinarySearch(existingServices, 0, existingServices.Length, new ServiceController(service.SERVICE_NAME), new ServiceComparer()); if (index > 0) { // Some NT Service with given name found NTService objService = new NTService( existingServices[index], existingServices[index].Status, service.intStartOrder, service.intStopOrder, service.SERVICE_NAME ); // Add found service to processed list of services Services.Add(objService); } } }
public ConfigForm() { InitializeComponent(); this.lblVersion.Text = Application.ProductVersion.ToString(); this.Text += " " + this.lblVersion.Text; #region Try to load settings file try { objSettigns = HotfixSettings.load(HotfixSettings.SETTINGS_FILENAME); objServiceProcessor = new ServiceProcessor(objSettigns, log); } catch (Exception inner) { string strMessage = string.Format("Failed to load settings file: {0}{1}", Environment.NewLine, Path.Combine(Application.StartupPath, HotfixSettings.SETTINGS_FILENAME) ); throw new System.InvalidOperationException(strMessage, inner); } #endregion // Try to load settings file }
public void Install() { try { log.WriteLine(LogType.Empty, ""); log.WriteLine(LogType.Empty, ""); string message = "INSTALLATION STARTED, PLEASE WAIT."; Console.WriteLine(message); log.WriteLine(LogType.Info, "HI058: " + message); //------------------------------------------------------- // Initilize installer object by settings given //------------------------------------------------------- settings = HotfixSettings.load(SettingsFile); //------------------------------------------------------- // Get last chance before installation //------------------------------------------------------- #region Get last chance before installation bool blnCancel = false; if (InstallationStartedEvent != null) { InstallationStartedEvent(ref blnCancel, settings.strGeneralDescription); if (blnCancel) { message = "INSTALLATION CANCELLED."; Console.WriteLine(message); log.WriteLine(LogType.Info, "HI014: " + message); return; } } #endregion // Get last chance before installation //------------------------------------------------------- // Print header of machine/user/os attributes //------------------------------------------------------- log.WriteLine(LogType.Info, string.Format(@"HI059: Machine :\\{0}\{1}", Environment.UserDomainName, Environment.MachineName)); log.WriteLine(LogType.Info, string.Format(@"HI060: Username :{0}", Environment.UserName)); log.WriteLine(LogType.Info, string.Format(@"HI061: Framework :{0}", Environment.Version.ToString())); log.WriteLine(LogType.Info, string.Format(@"HI062: OS Version :{0}", Environment.OSVersion.ToString())); log.WriteLine(LogType.Info, string.Format(@"HI063: Current directory:{0}", Environment.CurrentDirectory)); //------------------------------------------------------- // Initialize "hotfix root folder" (where installed components are) // relative to start up path //------------------------------------------------------- DirectoryInfo hRootFolder = null; if (hRootPath == null) { // determine path to installed components( relative/full qualified) if (settings.ComponentsFolderSetting.blnIsRelative) { hRootPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, settings.ComponentsFolderSetting.strFolder); } else { hRootPath = settings.ComponentsFolderSetting.strFolder; } } hRootFolder = new DirectoryInfo(hRootPath); //------------------------------------------------------- // Initialize list of installed components (processed directories) // and possible destinations //------------------------------------------------------- #region Initialize list of processed directories foreach (DirectoryInfo sub in hRootFolder.GetDirectories()) { //if not excluded from installed components if (!settings.IsExcluded(sub)) { // found out destination folder of installed component try { //exception will be thrown for some wrong arguments DirectoryInfo[] dest = DiscoverDest(sub); // add to list of installed components SrcDestPair pair = new SrcDestPair(sub, dest); processed.Add(pair); } catch (ArgumentException ex) { log.WriteLine(LogType.Error, "HI001: " + ex.ToString()); } } } //foreach if (processed.Count == 0) { string strMessage = string.Format("Nothing found to be installed.{0}Check hotfix root folder: {1}.{0}Check the exlusions list.", Environment.NewLine, hRootFolder.FullName); log.WriteLine(LogType.Info, "HI002: " + strMessage); return; } #endregion //------------------------------------------------------- // Load NT Service processor with ONLY actually installed services //------------------------------------------------------- objServiceProcessor = new ServiceProcessor(this.settings, this.log); //------------------------------------------------------- // Checking available free disk space //------------------------------------------------------- #region Checking available free disk space bool blnContinue = true; HotfixBackup objBackup = new HotfixBackup(settings, log, processed); if (this.settings.Backup.blnIsDoBackup) { Console.WriteLine("Checking available free disk space."); long lngAvailable = objBackup.CalclateAvailable(); long lngRequired = objBackup.CalculateRequiredFreeSpace(); message = string.Format("There is not enough free disk space for backuping. Required: {0}MB, Available: {1}MB", DriveInfoSystem.ToMB(lngRequired), DriveInfoSystem.ToMB(lngAvailable)); if (lngAvailable <= lngRequired) { log.WriteLine(LogType.Error, "HI055: " + message); blnContinue = false; return; } else { message = "[Checking available free disk space]"; log.WriteLine(LogType.Info, "HI057: " + message); message = string.Format("Required: {0}MB, Available: {1}MB", DriveInfoSystem.ToMB(lngRequired), DriveInfoSystem.ToMB(lngAvailable)); log.WriteLine(LogType.Info, "HI056: " + message); } } #endregion // Checking available free disk space //------------------------------------------------------- // Save current Status of service and Stop running services //------------------------------------------------------- Console.WriteLine("Stopping services."); log.WriteLine(LogType.Info, "HI003: " + "[STOP controlled services]"); if (objServiceProcessor.Stop()) { log.WriteLine(LogType.Info, "HI004: " + "Controlled services stopped successfully."); //------------------------------------------------------- // Backup installed components in format of hotfix //------------------------------------------------------- #region Backup installed components in format of hotfix if (this.settings.Backup.blnIsDoBackup) { Console.WriteLine("Backuping installed components."); message = "[Backuping installed components]"; log.WriteLine(LogType.Info, "HI008: " + message); blnContinue = objBackup.doBackup(); if (!blnContinue) { message = "Failed to backup installed components. Can't continue."; log.WriteLine(LogType.Error, "HI005: " + message); return; } } #endregion //------------------------------------------------------- // Process each item in list of components. // Copying from hotfix to destination folder. //------------------------------------------------------- Console.WriteLine("Installing components."); #region Process each installed directory log.WriteLine(LogType.Info, "HI006: " + "[INSTALLING Hotfix components]: " + processed.Count); foreach (SrcDestPair item in processed) { try { foreach (DirectoryInfo destPath in item.destDir) { if (destPath.Exists) { log.WriteLine(LogType.Info, "HI007: " + String.Format(@"FOLDER: ""{0}"" found, INSTALLING ...", destPath.FullName) ); xDirectory.Copy(item.srcDir, destPath); } else { //skipped log.WriteLine(LogType.Info, "HI008: " + String.Format(@"FOLDER: ""{0}"" is not installed, skipped.", destPath.FullName)); } } } catch (Exception ex) { log.WriteLine( LogType.Error, "HI009: " + String.Format("Failed during installing:{0}, Error:{1}", item.srcDir.ToString(), ex.ToString()) ); } } #endregion //------------------------------------------------------- // Fix/Update Xml configuration files according to specification // in <XmlFileFixes> for each <XmlFileFix> //------------------------------------------------------- Console.WriteLine("Applying changes in configuration files"); #region Xml Configuration Fixing log.WriteLine(LogType.Info, "HI010: " + "[Xml configuration files update]"); //make each xml fix as it appearing in XmlFileFixes section foreach (HotfixSettings.XmlFileFix filefix in settings.XmlFileFixes) { // find out which component we talk about to be able to find // configuration xml file for: filefix foreach (SrcDestPair comp in processed) { if (comp.srcDir.Name.ToLower() == filefix.folder.ToLower()) { //path to fix describing changes for: filefix string fileOfFixes = Path.Combine(comp.srcDir.FullName, filefix.update); XmlConfigurationHotfix componentFix = XmlConfigurationHotfix.Load(fileOfFixes); //get related pathes of patched files if (componentFix.objXMLContentFixes.Length > 0) { string[] pathes = new string[componentFix.objXMLContentFixes.Length]; int index = 0; foreach (XmlContentFix contentfix in componentFix.objXMLContentFixes) { pathes[index] = contentfix.contentXmlFilePath; index++; } foreach (DirectoryInfo path in comp.destDir) { //create absolute full qualified path to fixed xml foreach (XmlContentFix contentfix in componentFix.objXMLContentFixes) { contentfix.contentXmlFilePath = Path.Combine(path.FullName, contentfix.contentXmlFilePath); } try { //---> install fixes on Xml <--- componentFix.Install(log); } catch (Exception ex) { log.WriteLine( LogType.Error, "HI011: " + String.Format("Failed during Xml Configuration Fixing: {0}, Error:{1}", fileOfFixes, ex.ToString()) ); } // restore related path before next destination folder index = 0; foreach (XmlContentFix contentfix in componentFix.objXMLContentFixes) { contentfix.contentXmlFilePath = pathes[index]; index++; } } } break; } } //SrcDestPair } //filefix #endregion // Xml Configuration Fixing //------------------------------------------------------- // Clear Temporary ASP.NET files cache //------------------------------------------------------- Console.WriteLine("Clear Temporary ASP.NET files cache."); settings.mobjClearTempFiles.Do(log); //------------------------------------------------------- // Restore previous Status of controlled services //------------------------------------------------------- #region Restore controlled services Status log.WriteLine(LogType.Info, "HI012: " + "[RESTORE Status of controlled services ]"); Console.WriteLine("Starting services."); if (objServiceProcessor.Restore()) { log.WriteLine(LogType.Info, "HI013: " + "Status of controlled services restored successfully."); } else { //------------------------------------------------------- // Because KBXXXX of Microsoft not always ServiceController class able to start // service. I found workaround with starting some other process that tries // to start services again. This process takes as command line argument // of space separeted services names collected in error handler of // ServiceProcessor //------------------------------------------------------- System.Diagnostics.Process proc = new System.Diagnostics.Process(); try { proc.EnableRaisingEvents = false; proc.StartInfo.FileName = "Utilities.Hotfix.StartService.exe"; proc.StartInfo.UseShellExecute = true; proc.StartInfo.Arguments = objServiceProcessor.strFailedList; log.WriteLine(LogType.Error, "HI052: " + objServiceProcessor.strFailedList); proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal; proc.Start(); } catch { } } #endregion // restore controlled services Status //------------------------------------------------------- // Log that installation finished //------------------------------------------------------- string strMsgFinished = "Installation finished."; log.WriteLine(LogType.Info, "HI070: " + strMsgFinished); Console.WriteLine(strMsgFinished); } else { message = string.Format("Failed to stop controlled services. Can't continue."); log.WriteLine(LogType.Error, "HI015: " + message); } } catch (System.InvalidOperationException) { string message = string.Format("Failed to load hotfix instalation settings file: {0}{1} ", Environment.NewLine, this.SettingsFile); Console.WriteLine(); log.WriteLine(LogType.Error, "HI016: " + message); } finally { if (InstallationCompletedEvent != null) { InstallationCompletedEvent(settings.strGeneralDescription, "Please check log file."); } log.Show(); } }
public bool doBackup() { bool blnIsSucceed = true; //---------------------------------------------------------------------------- // folder of all backups //---------------------------------------------------------------------------- DirectoryInfo objBackups = new DirectoryInfo(strBackupFolder); //---------------------------------------------------------------------------- // get/create folder of backups //---------------------------------------------------------------------------- #region get/create folder of backups if (!objBackups.Exists) { try { objBackups.Create(); } catch (Exception objException) { log.WriteLine( LogType.Error, string.Format("HI017: " + "Failed to create root folder of backups: {0}", objException.ToString()) ); return(false); } } //---------------------------------------------------------------------------- // folder name of specific currently made backup //---------------------------------------------------------------------------- //create specific backup folder under the folder of backups strSpecificBackup = "Backup " + DateTime.Now.ToString("[dd-MM-yyyy HHmmss]"); DirectoryInfo objBackupFolder = null; try { objBackupFolder = objBackups.CreateSubdirectory(strSpecificBackup); } catch (Exception objException) { log.WriteLine( LogType.Error, string.Format("HI018: " + "Failed to create folder for specific backup: " + strSpecificBackup + ", Exception: {0}", objException.ToString()) ); return(false); } #endregion // get/create folder of backups //---------------------------------------------------------------------------- // backup each installed component //---------------------------------------------------------------------------- #region backup each installed component foreach (SrcDestPair objSrcDest in processed) { //---------------------------------------------------------- // Skip backup of component if marked in ComponentFiltes section of BackupExclusions //---------------------------------------------------------- if (this.settings.IsExcludedFromBackup(objSrcDest.srcDir.Name)) { log.WriteLine(LogType.Info, "HI069: " + String.Format(@"SKIPPED backuping of the component: ""{0}""", objSrcDest.srcDir.Name) ); continue; } // The path to currently backuped component string strBackuped = string.Empty; try { foreach (DirectoryInfo destPath in objSrcDest.destDir) { strBackuped = destPath.FullName; if (destPath.Exists) { log.WriteLine(LogType.Info, "HI019: " + String.Format(@"BACKUPING Component: ""{0}""", strBackuped) ); //create folder of backup for specific component DirectoryInfo objComponentBackup = objBackupFolder.CreateSubdirectory(objSrcDest.srcDir.Name); // Add masks for excluded files xDirectory.arrExcludeFileFilters = settings.mobjBackupExclusions.strGlobalFileExclusions; xDirectory.Copy(destPath, objComponentBackup); // !!! Only first installed component will be backuped to prevent overwriting break; } } #region Check and log possible multiple backup pathes if (objSrcDest.destDir.Length > 1) { int mintAmountExists = 0; string mstrBackuped = String.Empty; foreach (DirectoryInfo destPath in objSrcDest.destDir) { if (destPath.Exists) { mintAmountExists++; mstrBackuped = destPath.FullName; } } if (mintAmountExists > 1) { // Installed component will be copied to more than one destination // the only one destination(first) will be backuped log.WriteLine(LogType.Warning, "HI045: " + String.Format(@"Multiple destinations found for component: ""{0}"" ", objSrcDest.srcDir.ToString()) + String.Format("Only one component BACKUPED: {0}", mstrBackuped)); } } #endregion // Check and log possible multiple backup pathes } catch (Exception ex) { blnIsSucceed = false; #region Log: Failed during backup log.WriteLine( LogType.Error, "HI020: " + String.Format("Failed during backup: {0}, Error:{1}", strBackuped, ex.ToString()) ); #endregion // Log: Failed during backup break; } } #endregion // backup each installed component //---------------------------------------------------------------------------- // Prepare BIN folder of hotfix in Backup //---------------------------------------------------------------------------- #region Prepare BIN folder of hotfix in Backup //---------------------------------------------------------------------------- // 1) prepare backup bin folder with all needed exe and dll files //---------------------------------------------------------------------------- DirectoryInfo objFolderInstaller = objBackupFolder.CreateSubdirectory("Setup"); string[] arrFileToCopy = new string[] { "Utilities.Hotfix.dll", "Utilities.Hotfix.Config.exe", "Utilities.Hotfix.StartService.exe" }; // see also AppDomain Class usage example // http://207.46.16.251/en-us/library/system.appdomain.aspx FileInfo objExeInstaller = new FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location); objExeInstaller.CopyTo(Path.Combine(objFolderInstaller.FullName, objExeInstaller.Name), true); foreach (string strFileToCopy in arrFileToCopy) { FileInfo objDllInstaller = new FileInfo(strFileToCopy); objDllInstaller.CopyTo(Path.Combine(objFolderInstaller.FullName, objDllInstaller.Name), true); } //---------------------------------------------------------------------------- // Create and save UNDO configuration file //---------------------------------------------------------------------------- HotfixSettings objBackupSettings = new HotfixSettings(); objBackupSettings = HotfixSettings.load(settings.SettingsFileName); objBackupSettings.strGeneralDescription = " ROOLBACK: " + objBackupSettings.strGeneralDescription; //---------------------------------------------------------------------------- // Backup XML configuration files and update UNDO settings configuration //---------------------------------------------------------------------------- #region Backup XML configuration files and update UNDO settings configuration HotfixSettings.DestinationRootFolder objXmlConfig = new HotfixSettings.DestinationRootFolder(); objXmlConfig.TypeName = "Xml.Config.Backup"; objXmlConfig.path = ""; objXmlConfig.Default = false; objBackupSettings.DestinationRootFolders = (HotfixSettings.DestinationRootFolder[]) AppendItem(objBackupSettings.DestinationRootFolders, objXmlConfig, typeof(HotfixSettings.DestinationRootFolder)); foreach (HotfixSettings.XmlFileFix filefix in settings.XmlFileFixes) { // find out which component we talk about to be able to find // configuration xml file for: filefix foreach (SrcDestPair comp in processed) { if (comp.srcDir.Name.ToLower() == filefix.folder.ToLower()) { //path to fix describing changes for: filefix string fileOfFixes = Path.Combine(comp.srcDir.FullName, filefix.update); XmlConfigurationHotfix componentFix = XmlConfigurationHotfix.Load(fileOfFixes); //get related pathes of patched files if (componentFix.objXMLContentFixes.Length > 0) { foreach (DirectoryInfo path in comp.destDir) { //create absolute full qualified path to fixed xml foreach (XmlContentFix contentfix in componentFix.objXMLContentFixes) { string strFixedXmlFile = Path.Combine(path.FullName, contentfix.contentXmlFilePath); FileInfo objFixedXmlFile = new FileInfo(strFixedXmlFile); if (objFixedXmlFile.Exists) { HotfixSettings.FolderType objFolderType = new HotfixSettings.FolderType(); objFolderType.TypeName = objXmlConfig.TypeName; objFolderType.hotfix = "Xml.Config." + comp.srcDir.Name; objBackupSettings.FolderTypes = (HotfixSettings.FolderType[]) AppendItem(objBackupSettings.FolderTypes, objFolderType, typeof(HotfixSettings.FolderType)); HotfixSettings.FolderMapping objFolderMapping = new HotfixSettings.FolderMapping(); objFolderMapping.folder = objFolderType.hotfix; // ms-help://MS.MSDNQTR.2006JAN.1033/cpref/html/frlrfSystemIOPathClassGetDirectoryNameTopic.htm objFolderMapping.real = Path.GetDirectoryName(strFixedXmlFile); objBackupSettings.FolderMappings = (HotfixSettings.FolderMapping[]) AppendItem(objBackupSettings.FolderMappings, objFolderMapping, typeof(HotfixSettings.FolderMapping)); objBackupFolder.CreateSubdirectory(objFolderType.hotfix); //Copy file to backup directory objFixedXmlFile.CopyTo( Path.Combine(Path.Combine( objBackupFolder.FullName, objFolderType.hotfix), objFixedXmlFile.Name)); } //only first configuration file of processed component backuped break; } } } } } } #endregion // Backup XML configuration files and update UNDO settings configuration //Disable hotfix "backup" for "backup" objBackupSettings.Backup.blnIsDoBackup = false; //Zeroes configuration for exlclusions of backup objBackupSettings.mobjBackupExclusions.arrComponentFilters = new string[] {}; objBackupSettings.mobjBackupExclusions.strGlobalFileExclusions = new string[] {}; // Set components folder exactly to just created folder with backuped components objBackupSettings.ComponentsFolderSetting.blnIsRelative = false; objBackupSettings.ComponentsFolderSetting.strFolder = objBackupFolder.FullName; //xml fixes unrelevant for restoration from backup objBackupSettings.XmlFileFixes = new HotfixSettings.XmlFileFix[] {}; objBackupSettings.save(Path.Combine(objFolderInstaller.FullName, HotfixSettings.SETTINGS_FILENAME)); #endregion return(blnIsSucceed); }