5台电脑做视频网站服务器,京东网上商城官网,荷塘网站建设,wordpress 跳转 微信问题的提出
晚上翻着群里的聊天#xff0c;发现一个有趣的问题#xff1a;如何通过编码方式来判断一个dll或者exe为debug build还是release build#xff1f;由于没有太多的讨论#xff0c;所以我只好自己找点儿办法#xff0c;试图解决这个问题#xff0c;为夜生活带点…问题的提出
晚上翻着群里的聊天发现一个有趣的问题如何通过编码方式来判断一个dll或者exe为debug build还是release build由于没有太多的讨论所以我只好自己找点儿办法试图解决这个问题为夜生活带点刺激。于是便有了本文的探索和分析。
当然为了充分的调动起大家的主意省去不必要的google操作我觉得有必要对Debug和Release两种模式的异同进行一点提纲挈领式的分析从而为接下来的解决方案打好基础。
Debug Release
我们应用Visual Studio对代码文件进行F5操作Build时实际是发生了一系列语法检查、词法检查和编译过程通常情况下我们有两种Build模式这就是常说的Debug Build和Release Build。望文知意Debug Build模式通常应用于开发时便于调试反馈而Release Build则应用于部署时这是因为Release模式下编译器做了很多的优化操作代码冗余、循环优化等省去了对调试信息的记录。因此两种Build模式是各不相同的我们对其二者进行一点总结如下
Debug用于开发时Release用于部署时。Debug模式下将产生pdb文件用于保存状态信息和调试信息Release模式下不产生调试信息也没有pdb文件。Debug模式下System.Diagnostics.Debug.Write或WriteLine可以向跟踪窗口Output输出跟踪信息而Release模式下System.Diagnostics.Debug.WriteLine将被忽略。不过可以考虑System.Diagnostics.Trace.Write其人缘较好对Debug和Release左右通吃都可输出调试信息。Debug模式下#define DEBUG将作为默认预定义常量参与编译过程而在Release模式下该预编译将被省略。例如如果执行
#if DEBUGConsole.WriteLine(Hi);#endif
在Debug模式下Console.WriteLine(“Hi”)将参与编译而Release模式下会忽略该语句的执行。不过如果你手动添加
#define DEBUG
在两种模式下都会执行Console.WriteLine(“Hi”)的编译。究其原因是Visual Studio在默认情况下预定义了#define DEBUG我们可以通过开关来设置 关于预编译指令可详查《你必须知道的.NET》的相关章节。
解决方案
既然对Debug Build和Release Build有个基本的了解那么也由此可以推断我们解决开篇问题的依据。在.NET中以DebuggableAttribute来控制CLR如何处理模块代码规则而属性IsJITTrackingEnabled属性来标识运行库在代码生成过程中是否跟踪调试信息的标识如果IsJITTrackingEnabled为true表示运行库跟踪调试信息可推断为Debug Build模式如果IsJITTrackingEnabled为false表示运行库没有跟踪调试信息可推为Release Build模式。所以解决的方案最终着眼于对IsJITTrackingEnabled信息的获取上可想而知最简单的办法莫过于神兵利器——反射。
那么我们开始吧。
构建
首先我们创建一个AnyContext来承载通用的上下文服务在这里主要包含的就是
/// summary
/// A common context
/// /summary
/// remarks
/// Anytao, http://www.anytao.com
/// /remarks
public class AnyContext : IAnyObject
{public static DebugMode GetDebugMode(string assemblyName){ }
}
其中DebugMode是一个简单的枚举
/// summary
/// Debug mode type
/// /summary
/// remarks
/// Anytao, http://www.anytao.com
/// /remarks
public enum DebugMode
{Debug,Release
}
可向而知我们需要实现一个根据Assembly信息获取DebuggrableAttribute的Helper类既然是Helper类我们希望能够兼顾各种情况因此通过泛型方法是做好的选择具体实现如下
/// summary
/// Common helper
/// /summary
/// remarks
/// Anytao, http://www.anytao.com
/// /remarks
public static class Utils
{/// summary/// Get GetCustomAttribute/// /summary/// typeparam nameTCustomAttribute Type/typeparam/// param nameprovider/param/// returns/returnspublic static T GetCustomAttributeT(this ICustomAttributeProvider provider)where T : Attribute{var attributes provider.GetCustomAttributes(typeof(T), false);return attributes.Length 0 ? attributes[0] as T : default(T);}
}
此处的GetCustomAttribute被实现为扩展方法那么任何实现了ICustomAttributeProvider接口的类型都可以通过其获取CustomAttribute了例如Type、Assembly、Module、MethodInfo都可以实现对GetCustomAttribute的调用。
接下来GetDebugMode的逻辑就变得很简单我们传入assembly路径即可获取DebuggrableAttribute并由此推导IsJITTrackingEnabled的情况
public static DebugMode GetDebugMode(string assemblyName)
{if (string.IsNullOrEmpty(assemblyName)){throw new ArgumentNullException(assemblyName);}DebugMode ret DebugMode.Debug;try{// Get assebly by nameAssembly ass Assembly.LoadFile(assemblyName);// Get DebuggableAttribute infoDebuggableAttribute att ass.GetCustomAttributeDebuggableAttribute();ret att.IsJITTrackingEnabled ? DebugMode.Debug : DebugMode.Release;}catch (Exception){throw;}return ret;
}
好了这就是一个简单的判断逻辑在AnyContext中包含了很多诸如此类的上下文定义而GetDebugMode提供了本文开头的解决方案。
测试
新建两个project并分别以Debug模式和Release模式编译生成对应的exe或dll debugass.exereleaseass.exe新建TestProject并对GetDebugMode进行测试如下
[TestClass]
public class AnyContextTest
{[TestMethod]public void TestIsDebugOrRelease(){// Arrangestring ass1 D:\debugass.exe;string ass2 D:\releaseass.exe;// Act string mode1 AnyContext.GetDebugMode(ass1).ToString();string mode2 AnyContext.GetDebugMode(ass2).ToString();// AssetAssert.AreEqual(mode1, Debug);Assert.AreEqual(mode2, Release);}
}
一切OK你不妨试试。
注本测试在.NET 2.0及其以上版本测试通过如您有更多精力可对其以下版本进行分析。 参考文献
ms-help://MS.MSDNQTR.v90.chs/fxref_mscorlib/html/9f109812-3c14-dcb2-9aff-e18e20dc33ff.htmhttp://blogs.msdn.com/jb/archive/2006/06/14/631469.aspx