Skip to content

Instantly share code, notes, and snippets.

@chrismckelt
Last active December 21, 2017 03:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrismckelt/4b9172ae7d56ea18297c0418abbc7331 to your computer and use it in GitHub Desktop.
Save chrismckelt/4b9172ae7d56ea18297c0418abbc7331 to your computer and use it in GitHub Desktop.
Assembly Version Analyser
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