|
using System;
using System.Xml.XPath;
using Interop.COMAdmin;
namespace DevNetInstaller
{
/// <summary>
/// Responsible for analyzing project dependencies by their locations (Bin,GAC,COM+)
/// and return the data as XML.
/// </summary>
public class ReadProject
{
bool AllLevels = false;
string m_FilePath = "";
System.Text.StringBuilder XmlFile = new System.Text.StringBuilder();
XPathDocument oXmlReader;
#region CONSTRUCTORs
public ReadProject()
{
}
public ReadProject(string FilePath,bool bAllLevels)
{
// set depth of links
AllLevels = bAllLevels;
//set target file
m_FilePath = FilePath;
// if a project file load it as XMLDocument
if (m_FilePath.IndexOf (".dll") == -1 && m_FilePath.IndexOf (".exe") == -1)
oXmlReader = new XPathDocument(m_FilePath);
}
#endregion
/// <summary>
/// Get the Assembly name. if m_FilePath is EXE or DLL simply return it. else
/// get the assembly name from the project XML file (csproj).
/// </summary>
/// <returns>String - Assembly location</returns>
private string GetAssemblyName()
{
XPathNavigator oPath;
XPathNodeIterator oIter;
if (m_FilePath.IndexOf (".dll") > -1 || m_FilePath.IndexOf (".exe") > -1)
return m_FilePath;
string strAssName="",AssPath ;
try
{
oPath = oXmlReader.CreateNavigator();
oIter = oPath.Select("//Settings");
while (oIter.MoveNext())
{
strAssName = oIter.Current.GetAttribute("AssemblyName","");
}
AssPath = m_FilePath.Substring (0,m_FilePath.LastIndexOf("\\")+1) + "bin\\" + strAssName + ".DLL";
return AssPath;
}
catch ( Exception Err)
{
string a = Err.Message;
return "";
}
}
/// <summary>
/// get asembly references and place them between "<REFERS></REFERS>"
/// </summary>
/// <returns>String - XML holding reference</returns>
public string GetReferencToFile()
{
XmlFile.Append ("<REFS>");
AddReferenceToXml(GetAssemblyName());
XmlFile.Append ("</REFS>");
return XmlFile.ToString ();
}
/// <summary>
/// Check if given DLL register as COM+ component. looping through COM+
/// applications and application components. for each component look in
/// registry for component CLSID InprocServer32 value. if InprocServer32
/// value match given name return true.
/// </summary>
/// <param name="DllName" description="Full assembly name"></param>
/// <returns>bool</returns>
private bool IsDllInCom(string DllName)
{
bool RV=false;
COMAdminCatalogClass cat = new COMAdminCatalogClass ();
// Get Applications
ICatalogCollection col = cat.GetCollection("Applications") as ICatalogCollection;
col.Populate ();
System.Collections.IEnumerator oEnum = col.GetEnumerator ();
while(oEnum.MoveNext ())
{ string PackageKey = (string)((ICatalogObject)oEnum.Current).Key;
string CompKey = "Components";
ICatalogCollection oComponentsInPackage=null;
try
{
//get components
oComponentsInPackage = (ICatalogCollection)col.GetCollection(CompKey,((ICatalogObject)oEnum.Current).Key ) ;
}
catch (Exception err)
{
string s = err.Message ;
}
oComponentsInPackage.Populate ();
System.Collections.IEnumerator oCompEnum = oComponentsInPackage.GetEnumerator ();
while(oCompEnum.MoveNext ())
{
//Get component CLSID
string CLSID = (string)((ICatalogObject)oCompEnum.Current).get_Value("CLSID");
//Search CLSID in registry
Microsoft.Win32.RegistryKey RK = Microsoft.Win32.Registry.ClassesRoot;
string RegSearch = "CLSID\\" + CLSID + "\\InprocServer32";
RK = RK.OpenSubKey(RegSearch);
if (RK != null)
{
//check if InprocServer32 Assembly match given assembly
Object oRegValue = RK.GetValue("Assembly");
if (oRegValue != null && oRegValue.ToString() == DllName)
{
return true;
}
}
}
}
return RV;
}
/// <summary>
/// Get project files (ASP.NET pages)
/// </summary>
/// <param name="AssemPath" description="Project full path"></param>
/// <returns>string - Return xml string that holds project files.</returns>
public string GetFiles(string AssemPath)
{
XPathNavigator oPath;
XPathNodeIterator oIter;
if (m_FilePath.IndexOf (".dll") > -1 || m_FilePath.IndexOf (".exe") > -1)
return "";
XPathDocument oDoc = new XPathDocument(AssemPath);
System.Text.StringBuilder oSB = new System.Text.StringBuilder();
string FileName;
string AssPath = m_FilePath.Substring (0,m_FilePath.LastIndexOf("\\")+1);
oPath = oXmlReader.CreateNavigator();
oIter = oPath.Select("//File");
oSB.Append ("<Files>\n");
while (oIter.MoveNext())
{
if (oIter.Current.GetAttribute("DependentUpon","")=="")
{
FileName = m_FilePath.Substring (0,m_FilePath.LastIndexOf("\\")+1) + oIter.Current.GetAttribute("RelPath","");
// check if file exist to retun corresponding indication.
if (System.IO.File.Exists (FileName))
{
oSB.Append ("<File path=\"" + oIter.Current.GetAttribute("RelPath","") + "\" exist=\"true\"/>\n");
}
else
{
oSB.Append ("<File path=\"" + oIter.Current.GetAttribute("RelPath","") + "\" exist=\"false\"/>\n");
}
}
}
oSB.Append ("</Files>\n");
return oSB.ToString ();
}
/// <summary>
/// Get reference assemblies and check their locations on disk.
/// </summary>
/// <param name="AssemPath" description="Full Assembly path"></param>
private void AddReferenceToXml(string AssemPath)
{
System.Reflection.Assembly assem;
//Load assembly and get it reference assemblies into array
assem = System.Reflection.Assembly.LoadFrom(AssemPath);
System.Reflection.AssemblyName[] arrAsem = assem.GetReferencedAssemblies ();
for(int ienum = 0; ienum < arrAsem.Length ; ienum++)
{
string fullName =arrAsem[ienum].FullName;
string Name =arrAsem[ienum].Name;
string Path;
// if all levels set to false dont look for Sysytem.* assemblies.
if ((!AllLevels && (Name.ToLower().IndexOf("system.") == -1))||AllLevels)
{
// if assembly in gac and COM+ = COM+, GAC = GAC, COM+ but not in GAC = BIN (enforce assembly in COM+)
// to be in GAC!!!
if(AssemblyInGac(fullName,Name,out Path))
{
if(IsDllInCom(fullName))
{
XmlFile.Append ("<REF fullname=\"" + fullName + "\" path=\"" + Path + "\" exist=\"true\" loc=\"COM\">\n");
}
else
{
XmlFile.Append ("<REF fullname=\"" + fullName + "\" path=\"" + Path + "\" exist=\"true\" loc=\"GAC\">\n");
}
}
else if (AssemblyInBin(fullName,Name,out Path))
{
XmlFile.Append ("<REF fullname=\"" + fullName + "\" path=\"" + Path + "\" exist=\"true\" loc=\"BIN\">\n");
}
else if(AssemblyIsMSCore(fullName,Name,out Path))
{
XmlFile.Append ("<REF fullname=\"" + fullName + "\" path=\"" + Path + "\" exist=\"true\" loc=\"COR\">\n");
}
else
{
XmlFile.Append ("<REF fullname=\"" + fullName + "\" path=\"none\" exist=\"false\" loc=\"NON\">\n");
}
if (Path.IndexOf ("framework") == -1 && Path.IndexOf ("system.") == -1)
if (Path != "")
AddReferenceToXml(Path);
XmlFile.Append ("</REF>\n");
}
}
}
/// <summary>
/// Check if assembly in BIN directory
/// </summary>
/// <param name="inFullName"></param>
/// <param name="asmName"></param>
/// <param name="Path"></param>
/// <returns></returns>
private bool AssemblyInBin(string inFullName, string asmName,out string Path)
{
bool RV=false;
string AssPath;
// get assembly path
if (m_FilePath.IndexOf (".dll") > -1 || m_FilePath.IndexOf (".exe") > -1)
{
AssPath = m_FilePath.Substring (0,m_FilePath.LastIndexOf("\\")+1) + asmName + ".DLL";
}
else
{
AssPath = m_FilePath.Substring (0,m_FilePath.LastIndexOf("\\")+1) + "bin\\" + asmName + ".DLL";
}
// check if assembly exist
if (System.IO.File.Exists(AssPath))
{
//load assembky and check if it full name match the given inFullName
System.Reflection.Assembly assem = System.Reflection.Assembly.LoadFrom (AssPath);
if (assem.FullName == inFullName)
{
RV = true;
}
}
Path = AssPath;
return RV;
}
/// <summary>
/// check if Assembly in GAC
/// </summary>
/// <param name="inFullName"></param>
/// <param name="asmName"></param>
/// <param name="Path"></param>
/// <returns></returns>
private bool AssemblyInGac(string inFullName,string asmName,out string Path)
{
bool RV=false;
Path="";
//load assembly
System.Reflection.Assembly assem = System.Reflection.Assembly.LoadWithPartialName (inFullName);
if (assem != null)
{
//check if assembly in GAC
if (System.Runtime.InteropServices.RuntimeEnvironment.FromGlobalAccessCache (assem))
{
if (assem.FullName == inFullName)
{
RV = true;
Path = assem.CodeBase;
}
}
}
return RV;
}
/// <summary>
/// Well this function get DLLs that are MScore and not exist in GAC or BIN.
/// basically it the same as AssemblyInGac.
/// </summary>
/// <param name="inFullName"></param>
/// <param name="asmName"></param>
/// <param name="Path"></param>
/// <returns></returns>
private bool AssemblyIsMSCore(string inFullName,string asmName,out string Path)
{
bool RV=false;
Path="";
System.Reflection.Assembly assem = System.Reflection.Assembly.LoadWithPartialName (inFullName);
if (assem != null)
{
if (!System.Runtime.InteropServices.RuntimeEnvironment.FromGlobalAccessCache (assem))
{
if (assem.FullName == inFullName)
{
RV = true;
Path = assem.CodeBase;
}
}
}
return RV;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.