I have seen quite a few articles or tips talking about how to find out if an assembly is in debug mode or not (in the assembly), like this:
(C#) Determining whether the current build mode is Debug or Release[
^]
But there are scenarios that we need to tell an assembly is compiled as debug or release configuration (out of the assembly).
Because it is a small function, I try to put intact reference so that I do not include namespace:
public static bool IsInDebugMode(string FileName)
{
return IsInDebugMode(FileName, false);
}
public static bool IsInDebugMode(string FileName, bool IsAssemlbyName)
{
System.Reflection.Assembly assembly;
if (IsAssemlbyName)
assembly = System.Reflection.Assembly.Load(FileName);
else
assembly = System.Reflection.Assembly.LoadFile(FileName);
return IsInDebugMode(assembly);
}
public static bool IsInDebugMode(System.Reflection.Assembly Assembly)
{
var attributes = Assembly.GetCustomAttributes(typeof(System.Diagnostics.DebuggableAttribute), false);
if (attributes.Length > 0)
{
var debuggable = attributes[0] as System.Diagnostics.DebuggableAttribute;
if (debuggable != null)
return (debuggable.DebuggingFlags & System.Diagnostics.DebuggableAttribute.DebuggingModes.Default) == System.Diagnostics.DebuggableAttribute.DebuggingModes.Default;
else
return false;
}
else
return false;
}
The function is universal, works for library/gui/cui(console) assemblies, does not require developer to put customized property or functions to indicate.
You may wonder how I got this solution. I believe that the compiler must store some information in the assembly so that it can tell the debugging is supported or not.
First I run the IL DASM, open a debug as well as release version of a hello world application side by side, and compare the manifest, I found some differences like:
--debug version
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
--release version
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )
Immediately, I figured out that we can use reflection to get the
System.Diagnostics.DebuggableAttribute
custom attribute.
After some testing for GUI/CUI/Library applications, I believe that
System.Diagnostics.DebuggableAttribute.DebuggingModes.Default
is the one to distinguish between debug and release.
Details of the
DebuggableAttribute
value:
- debug mode:
- standard (Output = full), (01 00 07 01) = 263, Default | DisableOptimizations | IgnoreSymbolStoreSequencePoints | EnableEditAndContinue
- Project Settings -> Optimize code, (01 00 03 00) = 3, Default | IgnoreSymbolStoreSequencePoints
- Project Settings -> Advanced -> Output -> none, no custom attribute available (oops...)
- Project Settings -> Advanced -> Output -> pdb-only, no custom attribute available (oops...)
- release mode:
- standard (Output = pdb-only, Optimize Code), (01 00 02 00) = 2, IgnoreSymbolStoreSequencePoints
- Project Settings -> Advanced -> Output -> none, no custom attribute available (oops...)
- Project Settings -> Advanced -> Output -> full, (01 00 03 00) = 3, Default | IgnoreSymbolStoreSequencePoints
To sum up, as long as the user does not play with the "
Output
" method, we should be fairly sure if the application is being built in debug or release mode.