Stuff that's actually a debug build gets deployed all the time (by mistake, usually).
This is not cool, because there's a lot of overhead and garbage in assemblies
that were built in debug mode instead of release mode. It can even represent
a security risk in some cases. But in all cases, it means some serious performance
problems.
So how to check a folder for all the assemblies and be able to instantly see if any
of them are debug builds?
This little Windows Forms utility can do the trick. Here's the code:
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
namespace DebugBuild
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private bool IsAssemblyDebugBuild(string filepath)
{
return IsAssemblyDebugBuild(Assembly.LoadFile(Path.GetFullPath(filepath)));
}
private bool IsAssemblyDebugBuild(Assembly assembly)
{
bool isdebug = false;
foreach (var attribute in assembly.GetCustomAttributes(false))
{
DebuggableAttribute debuggableAttribute = attribute as DebuggableAttribute;
if (debuggableAttribute != null)
{
isdebug=
debuggableAttribute.DebuggingFlags.HasFlag(
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)
&&
debuggableAttribute.DebuggingFlags.HasFlag(
DebuggableAttribute.DebuggingModes.DisableOptimizations);
}
}
if (isdebug) break;
}
return isdebug;
}
private void button1_Click(object sender, EventArgs e)
{
var infos = new List<AssemblyInfo>();
DialogResult res= folderBrowserDialog1.ShowDialog();
if(res==DialogResult.OK)
{
string path = folderBrowserDialog1.SelectedPath;
var di = new DirectoryInfo(path);
FileInfo[] files = di.GetFiles();
foreach(FileInfo fi in files)
{
if( (fi.Name.ToLower().Contains(".dll") ||
fi.Name.ToLower().Contains(".exe")) &&
(!fi.Name.ToLower( ).Contains(".config") && !fi.Name.ToLower( ).Contains(".manifest")) )
{
string name = fi.Name;
bool isDebug = IsAssemblyDebugBuild(Path.Combine(path, fi.Name));
if (isDebug)
{
var ai = new AssemblyInfo {IsDebug = isDebug, Name = name};
infos.Add(ai);
}
}
}
this.dataGridView1.DataSource = infos;
}
}
}
public class AssemblyInfo
{
public string Name { get; set; }
public bool IsDebug { get; set; }
}
}
The key line in the code is this:
isdebug= !debuggableAttribute.DebuggingFlags.HasFlag(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints);
After .NET 1.1, all Release build assemblies have the above enum, "IgnoreSymbolStoreSequencePoints".
All you need to do is fire up the app, select a folder, and it will iterate through
each assembly (.dll or .exe) and display its "IsDebugBuild" status
in a GridView. I haven't tested it extensively so there is still a possibility
it could break on some strange extension names, but otherwise it works great. Included
in the solution is a web project with a standalone "script only" page
you can drop into your website that does the same thing.
You can download the complete Visual Studio solution here.