329 lines
14 KiB
C#
329 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using BridgeConnector.Lib.Thread;
|
|
|
|
namespace Component.All
|
|
{
|
|
/// <summary>
|
|
/// Calls GenericInstaller in order to perform an install/uninstall
|
|
/// * Does so in a threaded fashion *
|
|
/// </summary>
|
|
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<Component_Binary_Manager> s_binaryInstaller = null;
|
|
private static GenericInstaller<Component_Setup_Manager> s_setupInstaller = null;
|
|
private static SetupEvents s_SetupEvents = new SetupEvents();
|
|
|
|
/// <summary>
|
|
/// Perform a Threaded Install
|
|
/// </summary>
|
|
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<Component_Binary_Manager>();
|
|
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<Component_Setup_Manager>();
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Perform a Threaded Uninstall
|
|
/// </summary>
|
|
public static void PerformUninstall(string ComponentsSeperatedbySemiColonOrBlankForAll)
|
|
{
|
|
s_PerformUninstallCompleted = false;
|
|
s_PerformUninstallCompletedSuccessfully = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generic Install Class used for IManageComponents
|
|
/// </summary>
|
|
/// <typeparam name="T">IManageComponents responsible for Installing</typeparam>
|
|
public class GenericInstaller<T> : 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
|
|
|
|
/// <summary>
|
|
/// Construct the T Object
|
|
/// </summary>
|
|
public GenericInstaller()
|
|
{
|
|
_ComponentMGR = new T();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finalizer
|
|
/// </summary>
|
|
~GenericInstaller()
|
|
{
|
|
Dispose(true);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="setupEventObj"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Perform Install on the IManageComponents specified when Constructing the GenericInstaller Object
|
|
/// </summary>
|
|
/// <returns>true if no error occurs, false otherwise</returns>
|
|
public bool Install()
|
|
{
|
|
bool bErrorsOccured = false;
|
|
List<ComponentConfig.Component> successfullyInstalledComponents = new List<ComponentConfig.Component>();
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="setupEventObj"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Perform Uninstall on the IManageComponents specified when Constructing the GenericInstaller Object
|
|
/// </summary>
|
|
/// <param name="ComponentsSeperatedbySemiColonOrBlankForAll">coma-seperated Unique Labels of components to uninstall, blank for all</param>
|
|
/// <returns>true if no error occurs, false otherwise</returns>
|
|
public bool Uninstall(ref SetupEvents setupEventObj, string ComponentsSeperatedbySemiColonOrBlankForAll)
|
|
{
|
|
bool bErrorsOccured = false;
|
|
List<ComponentConfig.Component> successfullyUninstalledComponents = new List<ComponentConfig.Component>();
|
|
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
|
|
|
|
/// <summary>
|
|
/// Dispose of all extracted files
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
|
|
// Use SupressFinalize in case a subclass
|
|
// of this type implements a finalizer
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Make sure to call Dispose on the ComponentMGR for it to perform any cleanup
|
|
/// </summary>
|
|
/// <param name="disposing">if true, dispose ComponentMGR</param>
|
|
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
|
|
}
|
|
}
|