Last active
December 21, 2017 03:43
-
-
Save chrismckelt/4b9172ae7d56ea18297c0418abbc7331 to your computer and use it in GitHub Desktop.
Assembly Version Analyser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Globalization; | |
using System.IO; | |
using System.Linq; | |
using System.Reflection; | |
using System.Runtime; | |
namespace ScratchPad.Host.AssemblyAnalyser | |
{ | |
public class AssAnalyser | |
{ | |
public static readonly IList<string> Excludes = new List<string>(){"system", "microsoft" }; | |
public void Execute(string rootFolder, string excelOutputFile = @"c:\temp\assembly-versions.csv", string excelSheetName = "results") | |
{ | |
var files = Directory.GetFiles(rootFolder, "*.dll",SearchOption.AllDirectories); | |
Results = new List<AssAnalyserResult>(); | |
var seen = new List<string>(); | |
foreach (var file in files) | |
{ | |
string filename = Path.GetFileName(file); | |
if (Excludes.Any(x => filename.ToLowerInvariant().StartsWith(x))) continue; | |
Console.WriteLine(filename); | |
if (seen.Any(x=>x == filename)) | |
{ | |
continue; | |
} | |
var fileInfo = new FileInfo(file); | |
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(file); | |
if (fvi.CompanyName != null && (Excludes.Any(x=> fvi.CompanyName.ToLowerInvariant().Contains(x)))) continue; | |
if (LoadAssFromTempDomain(fileInfo, fvi) == false) | |
{ | |
seen.Add(filename); | |
try | |
{ | |
var assembly = Assembly.ReflectionOnlyLoadFrom(fileInfo.FullName); | |
Results.Add(new AssAnalyserResult() | |
{ | |
FullName = fileInfo.FullName, | |
FileVersion = fvi.FileVersion, | |
AssemblyVersion = AssemblyName.GetAssemblyName(assembly.Location).Version.ToString(), | |
ProcessorArchitecture = assembly.GetName().ProcessorArchitecture.ToString(), | |
Company = fvi.CompanyName, | |
Comments = fvi.Comments, | |
ProductName = fvi.ProductName, | |
Other = $"{fvi.FileDescription} {fvi.LegalCopyright}, {fvi.InternalName}" | |
}); | |
} | |
catch (Exception ex) | |
{ | |
System.Diagnostics.Trace.TraceWarning(string.Format(CultureInfo.InvariantCulture, | |
"Failed to load assembly '{0}': {1}", fileInfo.FullName, ex.Message)); | |
Errors.Add($"2nd-{fileInfo.FullName}", ex.Message); | |
Results.Add(new AssAnalyserResult() | |
{ | |
FullName = fileInfo.FullName, | |
FileVersion = fvi.FileVersion, | |
AssemblyVersion = "unknown", | |
ProcessorArchitecture = "unknown", | |
}); | |
} | |
} | |
} | |
using (var w = new StreamWriter(excelOutputFile)) | |
{ | |
foreach (var result in Results) | |
{ | |
var line = | |
$"{result.Company.Clean()},{result.FileName.Clean()},{result.FileVersion.Clean()},{result.AssemblyVersion.Clean()},{result.DirectoryName.Clean()},{result.ProcessorArchitecture.Clean()}, {result.ProductName.Clean()},{result.Other.Clean()}"; | |
w.WriteLine(line); | |
w.Flush(); | |
} | |
} | |
foreach (var err in Errors) | |
{ | |
System.IO.File.AppendAllText(@"c:\temp\errors.txt", $"{err.Key} {err.Value} {Environment.NewLine}"); | |
} | |
} | |
private bool LoadAssFromTempDomain(FileInfo fileInfo, FileVersionInfo fvi) | |
{ | |
AppDomain tempAppDomain = AppDomain.CreateDomain("tempAppDomain"); | |
try | |
{ | |
var assembly = tempAppDomain.Load(fileInfo.FullName); | |
Results.Add(new AssAnalyserResult() | |
{ | |
FullName = fileInfo.FullName.Clean(), | |
FileVersion = fvi.FileVersion.Clean(), | |
AssemblyVersion = AssemblyName.GetAssemblyName(assembly.Location).Version.ToString().Clean(), | |
ProcessorArchitecture = assembly.GetName().ProcessorArchitecture.ToString(), | |
Company = fvi.CompanyName, | |
Comments = fvi.Comments, | |
ProductName = fvi.ProductName, | |
Other = $"{fvi.FileDescription} {fvi.LegalCopyright}, {fvi.InternalName}" | |
}); | |
AppDomain.Unload(tempAppDomain); | |
return true; | |
} | |
catch (Exception ex) | |
{ | |
System.Diagnostics.Trace.TraceWarning(string.Format(CultureInfo.InvariantCulture, | |
"Failed to load assembly '{0}': {1}", fileInfo.FullName, ex.Message)); | |
Errors.Add(fileInfo.FullName, ex.Message); | |
return false; | |
} | |
finally | |
{ | |
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; | |
GC.Collect(); | |
} | |
} | |
public IList<AssAnalyserResult> Results { get; private set; } | |
public Dictionary<string,string> Errors { get; set; } = new Dictionary<string, string>(); | |
} | |
public class AssAnalyserResult | |
{ | |
public string FullName { get; set; } | |
public string FileVersion { get; set; } | |
public string AssemblyVersion { get; set; } | |
public string FileName => Path.GetFileName(FullName); | |
public string DirectoryName => Path.GetDirectoryName(FullName); | |
public string ProcessorArchitecture { get; set; } | |
public string Company { get; set; } | |
public string Comments { get; set; } | |
public string ProductName { get; set; } | |
public string Other { get; set; } | |
public override string ToString() | |
{ | |
return $"{nameof(FileName)}: {FileName}, {nameof(FileVersion)}: {FileVersion}, {nameof(AssemblyVersion)}: {AssemblyVersion}, {nameof(DirectoryName)}: {DirectoryName}"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment