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
}
}