using System; using System.Collections.Generic; using System.Linq; using System.Text; using Yaulw.Thread; namespace Installables.All { /// /// Calls GenericInstaller in order to perform an install/uninstall /// * Does so in a threaded fashion * /// public class GenericInstall { // Let the Caller know that a) the thread Completed b) it did so successfully public static bool s_PerformInstallCompleted = false; public static bool s_PerformInstallCompletedSuccessfully = false; // Let the Caller know that a) the thread Completed b) it did so successfully public static bool s_PerformUninstallCompleted = false; public static bool s_PerformUninstallCompletedSuccessfully = false; // Private ComponentMgmtObjects private static GenericInstaller s_binaryInstaller = null; private static GenericInstaller s_setupInstaller = null; private static SetupEvents s_SetupEvents = new SetupEvents(); /// /// Perform a Threaded Install /// public static void PerformInstall() { TStarter.ThreadMethod tMethod = delegate() { s_PerformInstallCompleted = false; s_PerformInstallCompletedSuccessfully = false; bool bBinaryInstallNeeded = false; bool bSetupInstallNeeded = false; // # Let's see if we need to update/install Binary Components if(s_binaryInstaller == null) s_binaryInstaller = new GenericInstaller(); bBinaryInstallNeeded = s_binaryInstaller.IsInstallNeeded(ref s_SetupEvents); // # Let's see if we need to update/install Setup Components if(s_setupInstaller == null) s_setupInstaller = new GenericInstaller(); bSetupInstallNeeded = s_setupInstaller.IsInstallNeeded(ref s_SetupEvents); // # Let's Install, Baby... if (bBinaryInstallNeeded || bSetupInstallNeeded) { // # Trigger Start Install Event s_SetupEvents.Raise_Before_Install_Event(); bool bBinarySuccess = true; bool bSetupbSuccess = true; // update/install Binary Components if (bBinaryInstallNeeded) bBinarySuccess = s_binaryInstaller.Install(); // update/install Setup Components if (bSetupInstallNeeded) bSetupbSuccess = s_setupInstaller.Install(); // # Trigger End Install Event if (bBinaryInstallNeeded || bSetupInstallNeeded) s_SetupEvents.Raise_After_Install_Event(); // # We fail if one of them fails s_PerformInstallCompletedSuccessfully = bBinarySuccess && bSetupbSuccess; } // # Let External Callers know that this Thread Completed s_PerformInstallCompleted = true; }; TStarter.StartThread(tMethod, "PerformInstall", System.Threading.ApartmentState.MTA, false, System.Threading.ThreadPriority.Normal); } /// /// Perform a Threaded Uninstall /// public static void PerformUninstall(string ComponentsSeperatedbySemiColonOrBlankForAll) { s_PerformUninstallCompleted = false; s_PerformUninstallCompletedSuccessfully = false; } /// /// Call this function to let every object know that either PerformInstall or PerformUninstall was called, /// the Gui then may have made some other modifications, and we are now completed /// public static void SetupMainCompleted() { // Notify all components that Setup is now complete s_SetupEvents.Raise_Ending_Setup_Event(); // # Imp! - We must call dispose on our Setup Objects if (s_binaryInstaller != null) { s_binaryInstaller.Dispose(); s_binaryInstaller = null; } if (s_setupInstaller != null) { s_setupInstaller.Dispose(); s_setupInstaller = null; } } } /// /// Generic Install Class used for IManageComponents /// /// IManageComponents responsible for Installing public class GenericInstaller : IDisposable where T : IManageComponents, IDisposable, new() { #region Private Members private T _ComponentMGR = default(T); private IInstallComponent[] _ComponentsToPerformWorkOn = null; private bool _disposed = false; #endregion #region Construction /// /// Construct the T Object /// public GenericInstaller() { _ComponentMGR = new T(); } /// /// Finalizer /// ~GenericInstaller() { Dispose(true); } #endregion #region Public Methods /// /// /// /// /// public bool IsInstallNeeded(ref SetupEvents setupEventObj) { if (_ComponentMGR.AreNewerComponentsAvailable()) { Common.Log.Info(String.Format("Newer Components available for Type {0}.", _ComponentMGR.GetType().Name)); _ComponentsToPerformWorkOn = _ComponentMGR.GetNewerComponents(ref setupEventObj); if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0) { Common.Log.Info(String.Format("Found {0} Newer Components.", _ComponentsToPerformWorkOn.Length)); return true; } } Common.Log.Info(String.Format("No Newer Components available for Type {0}.", _ComponentMGR.GetType().Name)); return false; } /// /// Perform Install on the IManageComponents specified when Constructing the GenericInstaller Object /// /// true if no error occurs, false otherwise public bool Install() { bool bErrorsOccured = false; List successfullyInstalledComponents = new List(); if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0) { // # Start Install foreach (IInstallComponent installComp in _ComponentsToPerformWorkOn) { ComponentConfig.Component component = installComp.GetComponent(); if (installComp.BEFORE_INSTALLING_COMPONENT()) { Common.Log.Info(String.Format("Installing Component {0} with Version {1}.", component.UniqueLabel, component.Version)); bool bInstallSuccess = installComp.INSTALL_COMPONENT(); bInstallSuccess = bInstallSuccess && installComp.AFTER_INSTALLING_COMPONENT(); if (bInstallSuccess) { Common.Log.Info(String.Format("Component {0} with version {1} was correctly installed.", component.UniqueLabel, component.Version)); successfullyInstalledComponents.Add(component); } else { bErrorsOccured = true; string msg = String.Format("Component {0} with version {1} was not correctly installed.", component.UniqueLabel, component.Version); Common.Log.Error(msg); } } } // # End Install // Add any installed components to the Installed Configuration foreach (ComponentConfig.Component component in successfullyInstalledComponents) _ComponentMGR.GetAllInstalledComponentsW().AddUpdateComponent(component.UniqueLabel, component.Version, component.FileName); // Write out the installed Configuration Common.WriteOutChangesToInstalledConfig(); } Common.Log.Info(String.Format("Exiting Install() for Type {0} with bErrorsOccured set to = {1}", _ComponentMGR.GetType().Name, bErrorsOccured)); return !bErrorsOccured; } /// /// /// /// /// public bool IsUninstallNeeded(ref SetupEvents setupEventObj, string ComponentsSeperatedbySemiColonOrBlankForAll) { if(_ComponentMGR.GetAllInstalledComponents() != null) { Common.Log.Info(String.Format("Installed Components available for Type {0}.", _ComponentMGR.GetType().Name)); _ComponentsToPerformWorkOn = _ComponentMGR.GetAllInstalledComponents(ComponentsSeperatedbySemiColonOrBlankForAll, ref setupEventObj); if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0) { Common.Log.Info(String.Format("Found {0} Components to Uninstall.", _ComponentsToPerformWorkOn.Length)); return true; } } Common.Log.Info(String.Format("No Installed Components to Uninstall for Type {0}.", _ComponentMGR.GetType().Name)); return false; } /// /// Perform Uninstall on the IManageComponents specified when Constructing the GenericInstaller Object /// /// coma-seperated Unique Labels of components to uninstall, blank for all /// true if no error occurs, false otherwise public bool Uninstall(ref SetupEvents setupEventObj, string ComponentsSeperatedbySemiColonOrBlankForAll) { bool bErrorsOccured = false; List successfullyUninstalledComponents = new List(); if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0) { // # Start Uninstall foreach (IInstallComponent uninstallComp in _ComponentsToPerformWorkOn) { if (!uninstallComp.SUPPORTS_UNINSTALL()) // Not all components support uninstall * although they should, we should allow for this contigency continue; ComponentConfig.Component component = uninstallComp.GetComponent(); if (uninstallComp.BEFORE_UNINSTALLING_COMPONENT()) { Common.Log.Info(String.Format("About to Uninstall Component {0} with Version {1}.", component.UniqueLabel, component.Version)); bool bUninstallSuccess = uninstallComp.UNINSTALL_COMPONENT(); if (!bUninstallSuccess) bErrorsOccured = true; bUninstallSuccess = bUninstallSuccess && uninstallComp.AFTER_UNINSTALLING_COMPONENT(); if (bUninstallSuccess) { Common.Log.Info(String.Format("Component {0} with version {1} was uninstalled.", component.UniqueLabel, component.Version)); successfullyUninstalledComponents.Add(component); } else { string msg = String.Format("Component {0} with version {1} was not uninstalled.", component.UniqueLabel, component.Version); Common.Log.Error(msg); } } } // # End Uninstall // Remove any uninstalled components from the Installed Configuration foreach (ComponentConfig.Component component in successfullyUninstalledComponents) _ComponentMGR.GetAllInstalledComponentsW().RemoveComponent(component.UniqueLabel); // Write out the installed Configuration Common.WriteOutChangesToInstalledConfig(); } Common.Log.Info(String.Format("Exiting Uninstall() for Type {0} with bErrorsOccured set to = {1}", _ComponentMGR.GetType().Name, bErrorsOccured)); return !bErrorsOccured; } #endregion #region IDisposable Members /// /// Dispose of all extracted files /// public void Dispose() { Dispose(true); // Use SupressFinalize in case a subclass // of this type implements a finalizer GC.SuppressFinalize(this); } /// /// Make sure to call Dispose on the ComponentMGR for it to perform any cleanup /// /// if true, dispose ComponentMGR protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { _ComponentMGR.Dispose(); _ComponentMGR = default(T); } // Indicate that the instance has been disposed. _disposed = true; } } #endregion } }