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

时间:2012-06-30 20:48:22

标签: c# architecture

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

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

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

还有其他想法吗?

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

3 个答案:

答案 0 :(得分:1)

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

A good overview of demands

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

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

Mechanism to extract specific IL (.NET Intermediate Language) signatures from an assembly

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

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

埃里克

答案 1 :(得分:1)

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

另一种选择是使用第三方工具并在编译时检查 - this question正是您需要的,包括示例,还有更多工具可以做到这一点(我只使用Resharper,但我认为它也可以完成任务。)

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

答案 2 :(得分:0)

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