如何防止或拦截对Directory.Delete的调用(path,true)

最近我正在调试一个“poof-all-customer-data-is-gone”问题。 它没有花太多时间来弄清楚错误的分支导致了Directory.Delete(customerRoot, true)代码行。 灾难性的一行是由一个常规的GUI开发人员编写的。 没有多少线可以导致这样的灾难。 所以我的问题是如何防止这个特定的电话。 ( DirectoryInfo.Delete()是第二个)。

这是我可能的解决方案的优先列表

  • 编译错误,没有第三方改变构建过程
  • 没有第三方的运行时拦截
  • 与第三方的运行时拦截(不改变构建过程)
  • 与第三方编译错误(我想PostSharp会这样做)
  • GUI开发人员关于客户如何喜欢他们数据的教育研讨会

还有其他想法吗?

我将提到我们的系统有一个专用服务(validation和记录)文件/文件夹删除。

要在运行时“拦截”调用,您可以使用FileSystemWatcher类,但它实际上不会阻止删除,只是让您知道它已经发生。 防止实际删除要困难得多。 Windows不提供Linux的ptracefunction,因此你无法拦截系统调用本身(这里有一篇关于它的文章,但可用性相当于我能说的内容)。 其他人建议的 – 设置访问权限和信任级别 – 可能会有效,但是当您确实需要删除某些内容并且“删除服务”只是.NET方法的包装时,您也会阻止它工作。

另一种选择是去第三方工具并在编译时检查这个问题 – 这个问题正是你需要的,包括例子,还有更多的工具可以做到这一点(我只使用Resharper,但我想象它也可以完成任务)。

但是,我不认为这就是重点。 你的开发者犯了一个错误,它打击了一些客户数据,没有人对此感到高兴。 它并不意味着你需要制定一个系统范围的规则并强制执行该规则,这意味着开发人员应该更好地测试他或她的代码和/或应该使用你提到的删除服务(无论是什么)。 无论你怎么努力,你都无法阻止人们做蠢事。 你不想花时间和金钱在Directory.Delete()方法周围制造防御工事只是为了发现其他人犯了一个不同的愚蠢错误,这个特殊的东西再也不会成为问题。 除非像你这样的问题(滥用Directory.Delete())在你的系统中比平常更容易发生,所以放手吧,专注于其他事情。

您可以将应用程序修改为不在完全信任下运行。 配置限制对物理磁盘的访问的信任级别。 看看FileIOPermission 。 请注意,这可以针对特定位置进行配置,从而为您提供相当的控制。

很好地了解需求

更新在考虑了这个之后,我还建议进行“保姆测试”。 如果您正在进行任何类型的测试,则可以添加一个查看程序集中所有类型的测试,并检查对任何FileSystem方法的调用。 任何此类呼叫都需要在白名单中,否则测试将失败。 我正在研究的项目使用它,它提供了很多价值。

更新2有关如何进行此类保姆测试的评论。 基本上,您需要使用reflection来获取所有方法,然后在IL中查找禁止调用。 这听起来比现在复杂得多。

从程序集中提取特定IL(.NET中间语言)签名的机制

更新3还有另一种更好的方法来做这种类型的保姆测试,它不直接涉及与IL混淆。 我在博客上发了一篇文章,告诉我如何做到这一点。

http://datatoknowledge.com/2012/09/10/nanny-tests/

埃里克

您可以在全局包含的命名空间中包含一个单独的Directory Class(和DirectoryInfo) – 这不会阻止某人使用System.IO.Directory.Delete,但这可能有助于捕获它并将其关闭,尤其是你包含一个相同的虚函数,它会抛出一个带有消息的exception。