Quick way to get all assemblies referenced in a BizTalk Server Solution

BizTalk Server uses a lot of assemblies, many of them are referenced and many times I need to understand how the  assembly is used and how many are referenced from it, many times to prepare a deployment or because I need to migrate an unknown environment.
Well, there are different ways to do that, one of these is querying the BizTalk management DB but it doesn’t contains all the information we need, normally only a first inheritance level.
I think the best and quick option is using the BizTalk Explorer Object model, I wrote a simple console application which is able to create an output file containing all the information I need.

The way is quite simple and it uses reflection to understand the assembly dependencies, below the code:

[sourcecode language=”csharp”]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.BizTalk.ExplorerOM;
using System.IO;
using System.Reflection;

namespace BizTalkAssemblyScanner
{
class Program
{
static void Main(string[] args)
{
StringBuilder somethingToWrite = new StringBuilder();
string fileName = "";
try
{
if (args.Length != 2)
throw new NotImplementedException();

Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
string servername = args[0].ToString();
string dbname = "BizTalkMgmtDb";

fileName = args[1].ToString();

Console.WriteLine("Load BizTalk configuration");

Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer btsCatalog1 = new Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer();
btsCatalog1.ConnectionString = "server=" + servername + ";database=" + dbname + ";Integrated Security=SSPI";

string localpath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

//TODO: fai in modo di inserire una string di esclusione dei vari assembly, esempio Microsoft.System., mscorlib
string starsep = "***********************************************************************";

foreach (Application application in btsCatalog1.Applications)
{
//if (application.Name != "FOR AFFINITY APP") continue;
Console.WriteLine("Looking into the application: " + application.Name);

somethingToWrite.AppendLine("");
somethingToWrite.AppendLine(starsep);
somethingToWrite.AppendLine(string.Format("Assemblies in the application name: {0}", application.Name));
somethingToWrite.AppendLine(starsep);
somethingToWrite.AppendLine("");
//Assembly
foreach (BtsAssembly assembly in btsCatalog1.Assemblies)
{
//Assembly affinity?
//if (assembly.DisplayName.IndexOf("Microsoft", 0) == 0 || assembly.DisplayName.IndexOf("System.", 0) == 0) continue;
try
{
somethingToWrite.AppendLine(assembly.DisplayName);

Assembly asmbase = Assembly.Load(assembly.DisplayName);
string text = string.Format("{0} – {1} – BTS:", assembly.DisplayName, asmbase == null ? "Loaded…" : "Not Loaded…", isbiztalkassemby(assembly.Name, application) ? "Yes" : "No");
Console.WriteLine(text);
somethingToWrite.AppendLine(text);
if (asmbase == null)
continue;
else
LoadAssemblyReferences(somethingToWrite, asmbase, application);

}
catch (Exception ex)
{
somethingToWrite.AppendLine(ex.Message);
}

}

}
File.WriteAllText(fileName, somethingToWrite.ToString());

}
catch (NotImplementedException ex)
{
Console.WriteLine("Arguments missing, -> BizTalkDeployer.exe servername filename");
}
catch (Exception ex)
{
somethingToWrite.AppendLine(ex.Message);
}
finally
{
File.WriteAllText(fileName, somethingToWrite.ToString());
Console.WriteLine("Done!");
Console.ReadLine();
}

}
static void LoadAssemblyReferences(StringBuilder somethingToWrite, Assembly asmbase,Application application)
{
// get first level references
AssemblyName[] referencedAssembly = asmbase.GetReferencedAssemblies();
Console.WriteLine("References used by {0}:", asmbase.FullName);
somethingToWrite.AppendLine("");
somethingToWrite.AppendLine(string.Format("References used by {0}:", asmbase.FullName));
foreach (AssemblyName assemblyName in referencedAssembly)
{
try
{
string text = string.Format("{0} – BTS {1}", assemblyName.FullName, isbiztalkassemby(assemblyName.Name, application) ? "Yes" : "No");
Console.WriteLine(text);
somethingToWrite.AppendLine(text);
//Assembly affinity?
//if (assemblyName.FullName.IndexOf("Microsoft.", 0) == 0 || assemblyName.FullName.IndexOf("System.", 0) == 0) continue;

Assembly asmreference = Assembly.Load(assemblyName.FullName);
AssemblyName[] referencedAssemblyRef = asmreference.GetReferencedAssemblies();

if (referencedAssemblyRef.Count() != 0)
return;
else

LoadAssemblyReferences(somethingToWrite, asmreference, application);

}
catch (Exception ex)
{
somethingToWrite.AppendLine(ex.Message);
}

}
}
static bool isbiztalkassemby(string assemblyname, Application application)
{
BtsAssembly btsasm = application.Assemblies[assemblyname];
return btsasm != null;

}

}
}
[/sourcecode]

I prefer to use a console application because is easier to manage in future scripting mechanism.

The console application command line is BizTalkAssemblyScanner.exe [Servername] [PathFileName]

and it produce an output as below:

Capture

You can download the .Net project HERE

 

Related blog posts