|
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Xml;
using System.Data;
namespace FindReferenceCollisions
{
public class FindCollisions
{
#region members
//dataset where all the dll references data is saved in
private ReferenceCollisionDataSet _ds = new ReferenceCollisionDataSet();
//all the app.config versions data is saved in
private List<AppRefVersion> _appList = new List<AppRefVersion>();
// the message for printing
private StringBuilder _Collisions = new StringBuilder();
#endregion
#region public methods
//return false if there is any collision or problem
public bool Find(string directory)
{
_ds.Clear();
_appList.Clear();
if (!System.IO.Directory.Exists(directory))
{
_Collisions.AppendLine("Directory not found");
return false;
}
//get all the file names from the directory
string[] files = System.IO.Directory.GetFiles(directory);
foreach (string file in files)
{
//check if i can reflect this file
if (CanReflected(file))
{
//if the file is app.config
//i take all the collisions data
if (file.IndexOf(".config") != -1)
AnalysisAppConfig(file);
else
//reflect all the dotnet dll and exe files
//and get all there references and insert them into dataset
FillDataSet(file);
}
}
//Find all the collisions
//and insert them into data set and into string
return FindCollisons();
}
#endregion
#region private methods
//check if i can reflect this file
private bool CanReflected(string file)
{
if ((file.IndexOf(".dll") != -1 || file.IndexOf(".exe") != -1) &&
(file.IndexOf("mscorlib.dll") == -1 &&
!file.Trim().StartsWith("System.") &&
file.Trim().IndexOf(".vshost.exe") == -1))
{
return true;
}
return false;
}
//check if this reference is not a system reference
private bool IsNotSystemRef(AssemblyName refName)
{
if (refName.Name.IndexOf("mscorlib") == -1 &&
!refName.Name.Trim().StartsWith("system") &&
!refName.Name.Trim().StartsWith("System"))
{
return true;
}
return false;
}
//reflect all the dotnet dll and exe files
//and get all there references and insert them into dataset
private void FillDataSet(string file)
{
try
{
ReferenceCollisionDataSet.DllTableRow dllRow = _ds.DllTable.NewDllTableRow();
Assembly asm = Assembly.LoadFile(file);
AssemblyName asmName = asm.GetName();
dllRow.Name = asmName.Name;
dllRow.Version = asmName.Version.ToString();
_ds.DllTable.Rows.Add(dllRow);
//run on all the references of the curent Assembly
foreach (AssemblyName refName in asm.GetReferencedAssemblies())
{
try
{
//check if this reference is not a system reference
if (IsNotSystemRef(refName))
{
ReferenceCollisionDataSet.ReferenceTableRow refRow = _ds.ReferenceTable.NewReferenceTableRow();
refRow.Dll_Name = asmName.Name;
refRow.Reference_Name = refName.Name;
refRow.Version = refName.Version.ToString();
_ds.ReferenceTable.Rows.Add(refRow);
}
}
catch
{
}
}
}
catch { }
}
//this method take the collision data out of the App.config
//using Xpath
private void AnalysisAppConfig(string exeFile)
{
if (File.Exists(exeFile))
{
XmlDocument doc = new XmlDocument();
doc.Load(exeFile);
XmlNode node = doc.FirstChild;
//find all the nodes with Xpath ="/configuration/runtime"
XmlNodeList nodeList = doc.SelectNodes("/configuration/runtime");
if (nodeList != null && nodeList.Count > 0)
{
foreach (XmlNode singleNode in nodeList)
{
if (singleNode.FirstChild != null)
{
foreach (XmlNode childNode in singleNode.FirstChild.ChildNodes)
{
XmlNode node1 = childNode.FirstChild;
XmlAttribute xmlAttributeName = node1.Attributes["name"];
XmlNode node2 = childNode.ChildNodes[1];
XmlAttribute xmlAttributeVersion = node2.Attributes["oldVersion"];
//insert all the data into the array of AppRefVersion
if (xmlAttributeVersion != null && xmlAttributeName != null)
_appList.Add(new AppRefVersion(xmlAttributeName.Value, xmlAttributeVersion.Value));
}
}
}
}
}
}
//this method run on all the data in ReferenceTable
//and get all the collisions
private bool FindCollisons()
{
foreach (ReferenceCollisionDataSet.ReferenceTableRow refRow in _ds.ReferenceTable.Rows)
{
ReferenceCollisionDataSet.ParentRefTableRow[] refParent = (ReferenceCollisionDataSet.ParentRefTableRow[])
_ds.ParentRefTable.Select(string.Format("Reference_Name='{0}' AND Version='{1}'", refRow.Reference_Name, refRow.Version));
bool IsInclude = false;
if (_appList != null)
{
//check if the version is between the what is write in the app.config
foreach (AppRefVersion appRefVersion in _appList)
{
IsInclude = appRefVersion.IsInVersion(refRow.Version, refRow.Reference_Name) | IsInclude;
}
}
if (!IsInclude)
{
if (refParent.Length > 0)
{
refParent[0].Count = refParent[0].Count + 1;
}
else
{
ReferenceCollisionDataSet.ParentRefTableRow newParentRow = _ds.ParentRefTable.NewParentRefTableRow();
newParentRow.Count = 1;
newParentRow.Version = refRow.Version;
newParentRow.Reference_Name = refRow.Reference_Name;
_ds.ParentRefTable.Rows.Add(newParentRow);
}
ReferenceCollisionDataSet.ChildRefTableRow newChildRow = _ds.ChildRefTable.NewChildRefTableRow();
newChildRow.Version = refRow.Version;
newChildRow.Reference_Name = refRow.Reference_Name;
newChildRow.Dll_Name = refRow.Dll_Name;
_ds.ChildRefTable.Rows.Add(newChildRow);
}
}
//delete all the Unnecessary Rows
DeleteUnnecessaryRows();
//write the collisions information into string
return WriteTostring();
}
//delete all the Unnecessary Rows like all the rows that dosent have collision
// and all the row that have only one reference
private void DeleteUnnecessaryRows()
{
List<DataRow> rowDelete = new List<DataRow>();
foreach (ReferenceCollisionDataSet.ParentRefTableRow refRow in _ds.ParentRefTable.Rows)
{
ReferenceCollisionDataSet.ParentRefTableRow[] refParent = (ReferenceCollisionDataSet.ParentRefTableRow[])
_ds.ParentRefTable.Select(string.Format("Reference_Name='{0}'", refRow.Reference_Name));
if (refParent.Length <= 1)
{
rowDelete.Add(refRow);
}
}
foreach (ReferenceCollisionDataSet.ParentRefTableRow parentRow in _ds.ParentRefTable.Rows)
{
DataRow[] rows = parentRow.GetChildRows("ParentRefTable_ChildRefTable");
if (rows.Length == 0)
rowDelete.Add(parentRow);
}
foreach (DataRow row in rowDelete)
{
row.Delete();
}
}
//write the collisions information into string
private bool WriteTostring()
{
//check if we use information from the app.config
if (_appList.Count > 0)
{
_Collisions.AppendLine(string.Format("Use App.config to cancel collisions "));
}
//check if there is any collisions at all
if (_ds.ParentRefTable.Rows.Count > 0)
{
List<string> referenceNames = new List<string>();
_Collisions.AppendLine(string.Format("Have version collision :"));
foreach (ReferenceCollisionDataSet.ParentRefTableRow pRow in _ds.ParentRefTable.Rows)
{
if (!referenceNames.Contains(pRow.Reference_Name))
{
_Collisions.AppendLine("--------------------------------------------------------------");
_Collisions.AppendLine(string.Format("Reference name : {0}", pRow.Reference_Name));
_Collisions.AppendLine("--------------------------------------------------------------");
foreach (ReferenceCollisionDataSet.ChildRefTableRow cRow in
(ReferenceCollisionDataSet.ChildRefTableRow[])_ds.ChildRefTable.Select(string.Format("Reference_Name='{0}'", pRow.Reference_Name)))
{
_Collisions.AppendLine(string.Format("Dll name : {0} Version : {1}", cRow.Dll_Name, cRow.Version));
}
}
referenceNames.Add(pRow.Reference_Name);
}
}
if (_ds.ParentRefTable.Rows.Count > 0)
return false;
return true;
}
#endregion
#region properties
public string CollisionsOutPut
{
get
{
return _Collisions.ToString();
}
}
public ReferenceCollisionDataSet Data
{
get
{
return _ds;
}
}
#endregion
}
internal class AppRefVersion
{
public Version _startVersion = null;
public Version _endVersion = null;
public string _ref = string.Empty;
public AppRefVersion(string reference, string version)
{
InsertRefVersion(reference, version);
}
public string Reference
{
get
{
return _ref;
}
}
//chack if the refernce is similar and the virsion is between
// the virsion of the app.config
public bool IsInVersion(string version, string reference)
{
Version newVersion = new Version(version);
if (_startVersion.CompareTo(newVersion) <= 0 &&
_endVersion.CompareTo(newVersion) >= 0 &&
_ref.Trim() == reference.Trim())
return true;
return false;
}
private void InsertRefVersion(string reference, string version)
{
try
{
string[] Split = version.Split('-');
_startVersion = new Version(Split[0]);
_endVersion = new Version(Split[1]);
_ref = reference;
}
catch
{
}
}
}
}
|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.