Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions BinaryDetail.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
Expand All @@ -9,12 +8,12 @@ namespace BinaryDetailer
[Serializable]
public class BinaryDetail
{

public BinaryDetail(FileInfo fileInfo)
{
FileInfo = fileInfo;
}

public string GroupId { get; internal set; }
public string Error { get; internal set; }
public FileInfo FileInfo { get; internal set; }
public ImageFileMachine ImageFileMachine { get; internal set; }
Expand All @@ -23,30 +22,26 @@ public BinaryDetail(FileInfo fileInfo)
public ProcessorArchitecture ProcessorArchitecture { get; internal set; }
public string TargetFrameworkAttribute { get; internal set; }
public string AssemblyVersion { get; internal set; }

public string FileVersion => FileVersionInfo.GetVersionInfo(FileInfo.FullName).FileVersion;

public string ProductVersion => FileVersionInfo.GetVersionInfo(FileInfo.FullName).ProductVersion;

public string AssemblyCompanyAttribute => FileVersionInfo.GetVersionInfo(FileInfo.FullName).CompanyName;
public string AssemblyCopyrightAttribute => FileVersionInfo.GetVersionInfo(FileInfo.FullName).LegalCopyright;


public static string[] CSVHeader
{
get
{
return new[]
{
"Full Path,FileName,AssemblyCompanyAttribute,AssemblyCopyrightAttribute,AssemblyVersion,FileVersion,ProductVersion,ImageRuntimeVersion,TargetFrameworkAttribute,PortableExecutableKinds,ImageFileMachine,ProcessorArchitecture,Error"
"Group Id, Full Path,FileName,AssemblyCompanyAttribute,AssemblyCopyrightAttribute,AssemblyVersion,FileVersion,ProductVersion,ImageRuntimeVersion,TargetFrameworkAttribute,PortableExecutableKinds,ImageFileMachine,ProcessorArchitecture,Error"
};
}
}


public string ToCsv()
{
return
"\"" + GroupId + "\"," +
"\"" + FileInfo.FullName + "\"," +
"\"" + FileInfo.Name + "\"," +
"\"" + AssemblyCompanyAttribute + "\"," +
Expand Down
2 changes: 0 additions & 2 deletions BinaryDetailFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
Expand Down Expand Up @@ -77,7 +76,6 @@ private AppDomain BuildChildDomain(AppDomain parentDomain)
evidence, setup);
}


private class BinaryDetailPopulator : MarshalByRefObject
{
[SuppressMessage("Microsoft.Performance",
Expand Down
10 changes: 10 additions & 0 deletions BinaryDetailer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,16 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="BinaryDetail.cs" />
<Compile Include="BinaryDetailFactory.cs" />
<Compile Include="Export.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand All @@ -50,6 +54,12 @@
<Version>1.5.1</Version>
</PackageReference>
<BinSkimFiles Include="$(PkgMicrosoft_CodeAnalysis_BinSkim)\tools\netcoreapp2.0\**\*.*" />
<PackageReference Include="Microsoft.Office.Interop.Word">
<Version>15.0.4797.1004</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Content Include="GroupingConfig.xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="CopyBinSkim" AfterTargets="Build">
Expand Down
275 changes: 275 additions & 0 deletions Export.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;

// Use of this library requires an install of Microsoft office
using Microsoft.Office.Interop.Word;

namespace BinaryDetailer
{
public class Export
{
readonly List<string> ExcludeNames = new List<string>();

public Export(List<string> excludeNames)
{
ExcludeNames = excludeNames;
}

public void GroupBinary(List<BinaryDetail> binaryDetails, string xmlFilePath)
{
try
{
// Load xml config file
XDocument xmlDoc = XDocument.Load(xmlFilePath);

// Loop through the binaries
foreach (var binaryDetail in binaryDetails)
{
// Set an escape from the loop once match is found
bool groupIdSet = false;

// Loop through each "group" element. I.E Company name
foreach (XElement group in xmlDoc.Root.Elements("group"))
{
if (groupIdSet == true) break;

string groupName = group.Attribute("name").Value;

// Check if the binary has a match in the config xml
if (binaryDetail.AssemblyCompanyAttribute == groupName)
{
// Loop through each "dll" element in the matching group
// It is neccessarry to find the group first. It is possible a dll could be used in
// another library in which case a license check needs to be done.
foreach (XElement dll in group.Elements("dll"))
{
// Check if the "dllname" attribute matches a "FileInfo.Name"
string dllName = dll.Attribute("dllname")?.Value ?? dll.Value;

// If the dll in the config matches, set groupid
if (binaryDetail.FileInfo.Name == dllName)
{
binaryDetail.GroupId = groupName;
groupIdSet = true;
break;
}
}
}
else
{
// If nothing matches
binaryDetail.GroupId = "Unknown";
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

public void CreateReport(List<BinaryDetail> binaryDetails)
{
string csvFileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
Guid.NewGuid() + ".csv");

File.Create(csvFileName).Close();
File.AppendAllLines(csvFileName, BinaryDetail.CSVHeader);

foreach (var binaryDetail in binaryDetails)
{
bool include = true;
foreach (string excludeName in ExcludeNames)
{
if ((binaryDetail.AssemblyCompanyAttribute != null && binaryDetail.AssemblyCompanyAttribute.ToLower().Contains(excludeName)) ||
(binaryDetail.AssemblyCopyrightAttribute != null && binaryDetail.AssemblyCopyrightAttribute.ToLower().Contains(excludeName)))
{
include = false;
}
}

if (include == false) continue;

File.AppendAllLines(csvFileName, new[] { binaryDetail.ToCsv() });
}

Console.WriteLine("File created at " + csvFileName);
}

public void CreateWordDoc(List<BinaryDetail> binaryDetails)
{
try
{
string wordFileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
Guid.NewGuid() + ".docx");

// Create an instance for word app
Application winword = new Application
{
ShowAnimation = false,
Visible = false
};

// Create a missing variable for missing value
object missing = Missing.Value;

// Create a new document
Document document = winword.Documents.Add(ref missing, ref missing, ref missing, ref missing);
document.PageSetup.Orientation = WdOrientation.wdOrientLandscape;

// Add header into the document
foreach (Section section in document.Sections)
{
//Get the header range and add the header details.
Range headerRange = section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
headerRange.Fields.Add(headerRange, WdFieldType.wdFieldPage);
headerRange.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
headerRange.Font.ColorIndex = WdColorIndex.wdBlue;
headerRange.Font.Size = 10;
headerRange.Text = "Binary Detailer";
}

// Add the footers into the document
foreach (Section wordSection in document.Sections)
{
//Get the footer range and add the footer details.
Range footerRange = wordSection.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
footerRange.Font.ColorIndex = WdColorIndex.wdDarkRed;
footerRange.Font.Size = 10;
footerRange.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
footerRange.Text = "Github repository: https://github.com/stuartjsmith/binarydetailer";
}

// Adding text to document
document.Content.SetRange(0, 0);
string firstLine = "Binary Detailer is a method of outputting binary details such as net framework, " +
"64-bit compatibility, version etc. Given a directory name, it will iterate dll and exe files " +
"and output the results to a csv file.";

document.Content.Text = firstLine + Environment.NewLine;

// Add paragraph with Heading 1 style
Paragraph para1 = document.Content.Paragraphs.Add(ref missing);
object styleHeading1 = "Heading 1";
para1.Range.set_Style(ref styleHeading1);
para1.Range.Text = "Binary Details";
para1.Range.InsertParagraphAfter();

// Create a table
Table table = document.Tables.Add(para1.Range, binaryDetails.Count + 1, 5, ref missing, ref missing);

// Define column headings
WordColumnHeadings(table);

// Add table borders
table.Borders.Enable = 1;

// Loop through each binary and add to the table.
foreach (var binaryDetail in binaryDetails.Select((value, i) => new { i, value }))
{
bool include = true;

foreach (string excludeName in ExcludeNames)
{
if ((binaryDetail.value.AssemblyCompanyAttribute != null && binaryDetail.value.AssemblyCompanyAttribute.ToLower().Contains(excludeName)) ||
(binaryDetail.value.AssemblyCopyrightAttribute != null && binaryDetail.value.AssemblyCopyrightAttribute.ToLower().Contains(excludeName)))
{
include = false;
}
}

if (include == false) continue;

// Passing the index + 2 as there is a heading column to overcome.
WordRowData(binaryDetail.i + 2, table, binaryDetail.value);
}

//Save the document
object filename = wordFileName;
document.SaveAs2(ref filename);
document.Close(ref missing, ref missing, ref missing);
document = null;
winword.Quit(ref missing, ref missing, ref missing);
winword = null;

Console.WriteLine("Word Document created at " + filename);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

public void WordColumnHeadings(Table firstTable)
{
// Loop through each cell in the row
foreach (Cell cell in firstTable.Rows[1].Cells)
{
// Switch between the columns
switch (cell.ColumnIndex)
{
case 1:
cell.Range.Text = "Group ID";
break;
case 2:
cell.Range.Text = "Company Name";
break;
case 3:
cell.Range.Text = "File Name";
break;
case 4:
cell.Range.Text = "Assembly Version";
break;
case 5:
cell.Range.Text = "File Version";
break;
}

// Format properties goes here
cell.Range.Font.Bold = 1;
cell.Range.Font.Name = "verdana";
cell.Range.Font.Size = 10;

// Cell shading
cell.Shading.BackgroundPatternColor = WdColor.wdColorGray25;

// Center alignment for the Header cells
cell.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
cell.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
}
}

public void WordRowData(int index, Table firstTable, BinaryDetail binaryDetail)
{
// Loop through each cell in the row
foreach (Cell cell in firstTable.Rows[index].Cells)
{
// Switch between the columns
switch (cell.ColumnIndex)
{
case 1:
cell.Range.Text = binaryDetail.GroupId;
break;
case 2:
cell.Range.Text = binaryDetail.AssemblyCompanyAttribute;
break;
case 3:
cell.Range.Text = binaryDetail.FileInfo.Name;
break;
case 4:
cell.Range.Text = binaryDetail.AssemblyVersion;
break;
case 5:
cell.Range.Text = binaryDetail.FileVersion;
break;
}
}
}
}
}
17 changes: 17 additions & 0 deletions GroupingConfigExample.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<groups>
<group name="Infragistics">
<dll>Infragistics.Documents.Core.dll</dll>
</group>
<group name="Microsoft Corporation">
<dll>Microsoft.Build.Tasks.Core.resources.dll</dll>
</group>
<group name="Notepad++ Community">
<dll dllname ="nppPluginList.dll"/>
<dll dllname ="NppExport.dll"/>
</group>
<group name="Don HO don.h@free.fr">
<dll dllname ="mimeTools.dll"/>
<dll dllname ="NppConverter.dll"/>
</group>
</groups>
Loading