【发布时间】:2011-03-01 08:38:27
【问题描述】:
我有一个在目录中查找文件的旧应用程序。它不能很好地处理丢失的文件。我想要做的是“捕获”文件未找到错误,并将另一个文件发送回调用应用程序。类似于您如何在网络服务器上处理 404 错误并根据所请求的 URL 返回某些内容,本地文件系统除外。
这可能吗?更可取的是,在 .Net 中是否可行?
【问题讨论】:
标签: .net windows error-handling filesystems file-not-found
我有一个在目录中查找文件的旧应用程序。它不能很好地处理丢失的文件。我想要做的是“捕获”文件未找到错误,并将另一个文件发送回调用应用程序。类似于您如何在网络服务器上处理 404 错误并根据所请求的 URL 返回某些内容,本地文件系统除外。
这可能吗?更可取的是,在 .Net 中是否可行?
【问题讨论】:
标签: .net windows error-handling filesystems file-not-found
是的,您所描述的都是可能的。
我建议使用filesystem filter driver or mini filter 来处理这种类型的事情,尽管这在.Net 中无法完成。
我建议的方式可能是在文件系统级别捕获所有内容的最合适的方式。
【讨论】:
您可以通过拦截对 Win API 函数 CreateFile 的调用来做到这一点。这需要dll注入。在 .NET 中,您可以使用这个库:easyhook.codeplex.com
【讨论】:
如果商业解决方案是可以接受的,那么像 Eldos CallbackFilter 这样的解决方案可能符合要求:
http://www.eldos.com/cbflt/spec.php
我并没有完全将它用于您的目的,但您当然可以拦截文件系统调用,在那里您可以检查文件是否存在,如果不存在则创建一个虚拟文件。
事实证明,这对于清理行为不良的遗留应用程序可能要简单得多。
【讨论】:
如果您知道要打开文件的进程中的代码在哪里,您可以围绕它编写一个像调试器一样的包装进程,拦截调用,自己检查它是否存在,如果不存在,用不同的文件名替换文件名。
类似:
CreateProcess(bla bla, DEBUG_ONLY_THIS_PROCESS, bla bla);
SetBreakPoint(address of code to set breakpoint)
{
ReadProcessMemory to save off byte for breakpoint
WriteProcessMemory 0xCC to set breakpoint
FlushInstructionCache
}
while (TRUE == bContinue)
{
bContinue = WaitForDebugEvent(&debugEvent);
switch (dwDebugEventCode)
{
case EXCEPTION_BREAKPOINT:
// Read the file name from memory, check if it exists, if not, replace it with
// new file name using the same length in memory :)
// Replace your code byte you read out when you set the breakpoint
}
}
另一种方法是用您自己对 CreateFile 的调用(或他们在相关应用程序中使用的任何方法)覆盖函数调用表。在这里查找 API 挂钩,甚至 Dll 注入都可能对您有所帮助。
【讨论】: