编写代码时,我经常在代码中放置调试消息。调试消息由记录器类处理,记录器类以调试模式将消息输出到文件,并在释放模式下丢弃它们。
它看起来像这样:
class Logger : IDisposable
{
private StreamWriter m_Logger = null;
public void Start(string logFile)
{
m_Logger = new StreamWriter(logFile);
m_Logger.AutoFlush = true;
}
public void Dispose()
{
if (m_Logger != null) m_Logger.Dispose();
}
public void WriteLine(string message)
{
if (m_Logger != null) m_Logger.WriteLine(message);
}
}
实例在启动时创建,可从Program
类访问。然后我检查这样的调试:
#if DEBUG
Program.Log.Start("app.log");
#endif
这很好用,因为它在调试模式下转储调试信息,而不是在发布模式下。但是,如果我通过strings
等实用程序运行发行版可执行文件,我仍然可以看到调试字符串。我宁愿让它们完全脱离发布版本,以帮助防止逆向工程。
到目前为止,我发现的唯一解决方案是将所有调试消息包装在预处理器条件中:
// < some code here >
#if DEBUG
Program.Log.WriteLine("Some debug message.");
#endif
// < more code here >
这非常乏味和丑陋。我的第一个想法是使用某种预处理器宏,但C#不支持它们。有没有比我现在使用的更优雅的解决方案?
答案 0 :(得分:6)
为避免在每次WriteLine调用中使用#if-#endif,请尝试在记录器方法本身上使用ConditionalAttribute:
[Conditional("DEBUG")]
public void WriteLine(string message)
{
if (m_Logger != null) m_Logger.WriteLine(message);
}
如果发布版本,这将从MSIL中排除。
将ConditionalAttribute应用于方法指示编译器 不应将对该方法的调用编译到Microsoft中 中间语言(MSIL),除非条件编译符号 与ConditionalAttribute关联的是已定义的。应用 ConditionalAttribute指向属性表示该属性 除非条件编译,否则不应将其发送到元数据 符号已定义
答案 1 :(得分:0)
1)将#ifdef放在log方法的主体中,这样就不必在每条日志消息周围放置定义
2)如果您正在尝试阻止逆向工程,请对代码进行模糊处理,这会加密字符串,但这不是故障安全。
3)您可以使用PostSharp之类的东西在http://www.sharpcrafters.com/solutions/logging
之后主动删除MSIL中的代码