using System; using System.Collections.Generic; using System.Linq; using System.Text; using Yaulw.File; using System.Xml.Serialization; using System.Collections; using Yaulw.Xml; using System.Resources; using System.Reflection; using System.IO; using Yaulw.Tools; using Yaulw.Assembly; namespace Installables.All { /// /// Responsible for extracting the Components that are embedded in this dll /// into the temporary directory for the installer to consume /// public class Component_Binary_Manager : IDisposable, IManageComponents { #region Private Members private bool _disposed = false; private Dictionary _componentsLoaded = new Dictionary(); #endregion #region Construction /// /// Constructor /// public Component_Binary_Manager() { } /// /// Finalizer /// ~Component_Binary_Manager() { Dispose(true); } #endregion #region IManageComponents Members /// /// Checks if there are Newer Components embedded then that were installed on the system /// /// true, if newer components were found, false otherwise public bool AreNewerComponentsAvailable() { //# If nothing is installed, no need to continue if (GetAllInstalledComponents() == null) return true; // if the lengths don't match, something must get installed if (GetAllInstalledComponents().Length != GetAllEmbeddedComponents().Length) return true; // # Otherwise, let's determine 1 by 1 foreach (ComponentConfig.Component component in GetAllEmbeddedComponents()) { int nIndex = Common.GetIndexForComponentUniqueLabel(component.UniqueLabel, GetAllInstalledComponents()); if (nIndex == -1) return true; else if(GetAllInstalledComponents()[nIndex].CompareTo(component) != 0) return true; } return false; } /// /// Returns the Component Definition containing the temporary file (extracted component) /// for all Newer components found on the system /// /// Setup Event Object is passed, for component manager to pass down to it's components /// a list of newer binary components, or empty list for none public IInstallComponent[] GetNewerComponents(ref SetupEvents setupEventObj) { // # Extract all, or let's determine 1 by 1 and extract bool bInstalledCompsFound = (GetAllInstalledComponents() != null); foreach (ComponentConfig.Component component in GetAllEmbeddedComponents()) { bool bExtract = true; if (bInstalledCompsFound) { int nIndex = Common.GetIndexForComponentUniqueLabel(component.UniqueLabel, GetAllInstalledComponents()); if (nIndex != -1) bExtract = (GetAllInstalledComponents()[nIndex].CompareTo(component) != 0); } // mark component for Installation * Extract to File System * if (bExtract) { if (!ExtractComponentFromResourceToTempFileLocation(component)) Common.Log.Error(String.Format("Failed to Extract Component {0}", component.UniqueLabel)); } } List ComponentsToInstall = new List(); if (_componentsLoaded.Count > 0) { foreach(Assembly asm in _componentsLoaded.Values) { IInstallComponent installComp = null; Type[] types = asm.GetTypes(); foreach (Type t in types) { if (t.GetInterface(typeof(IInstallComponent).Name) != null) { installComp = (IInstallComponent) asm.CreateInstance(t.FullName); break; } } // Check IInstallComponent was found if (installComp == null) { Common.Log.Error(String.Format("Component {0} contains no IInstallComponent Definition.", AssemblyW.GetAssemblyName(asm))); continue; } // Check if class also implements ISetup if(installComp is ISetup) ((ISetup) installComp).ComponentLoaded(ref setupEventObj); // Add to Install Components ComponentsToInstall.Add(installComp); } } return ComponentsToInstall.ToArray(); } /// /// Retrieves the list of all installed components, in order to uninstall /// /// a list of all installed components, null otherwise public IInstallComponent[] GetAllInstalledComponents(string ComponentsSeperatedbySemiColonOrBlankForAll, ref SetupEvents setupEventObj) { // TO DO: return null; } /// /// Retrieves the list of all installed components /// /// a list of all installed components, null otherwise public ComponentConfig.Component[] GetAllInstalledComponents() { if (Common.InstalledConfig != null && Common.InstalledConfig.BinaryComponents.Components.Length > 0) return Common.InstalledConfig.BinaryComponents.Components; return null; } /// /// Retrieves the list of all installed componentsW /// /// a list of all installed componentsW, null otherwise public ComponentConfig.ComponentW GetAllInstalledComponentsW() { return Common.InstalledConfig.BinaryComponents; } /// /// Retrieves the list of all Embedded components /// /// a list of all embedded components, null otherwise public ComponentConfig.Component[] GetAllEmbeddedComponents() { if (Common.EmbeddedConfig != null && Common.EmbeddedConfig.BinaryComponents.Components.Length > 0) return Common.EmbeddedConfig.BinaryComponents.Components; return null; } #endregion #region Private Helpers /// /// Private Helper to physically extract the bits from the resource and write them to a temporary /// file location /// /// Component, whose files are to be extracted /// true, if successful, false otherwise private bool ExtractComponentFromResourceToTempFileLocation(ComponentConfig.Component component) { if (component != null) { // Extract the component to the Temp Directory, // if it is not already there... for (int i = 0; i < component.FileNames.Length; ++i) { // First try loading the assembly string asmName = "Component.Binary." + component.UniqueLabel; Assembly asm = Assembly.Load(asmName); if (asm == null) return false; else _componentsLoaded[component.UniqueLabel] = asm; // <- imp string FileName = component.FileNames[i]; string TempFileNameNPath = component.TempFileNamesNPath[i]; if (!File.Exists(TempFileNameNPath)) { using (BinaryReader br = new BinaryReader(asm.GetManifestResourceStream(asmName + "." + FileName))) using (BinaryWriter bw = new BinaryWriter(new FileStream(TempFileNameNPath, FileMode.Create))) { byte[] buffer = new byte[64 * 1024]; int numread = br.Read(buffer, 0, buffer.Length); while (numread > 0) { bw.Write(buffer, 0, numread); numread = br.Read(buffer, 0, buffer.Length); } bw.Flush(); } } } return true; } return false; } #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 conserve disk space, to delete all files that were extracted /// by this program /// /// if true, delete all files extracted by this dll protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // When Disposing, Delete all Temporary Files on the System that may exist foreach (ComponentConfig.Component component in GetAllEmbeddedComponents()) { foreach (string tFileNameNPath in component.TempFileNamesNPath) { if (File.Exists(tFileNameNPath)) File.Delete(tFileNameNPath); } } _componentsLoaded.Clear(); _componentsLoaded = null; } // Indicate that the instance has been disposed. _disposed = true; } } #endregion } }