我有一个在目录中查找文件的旧应用程序。它不能很好地处理丢失的文件。我想要做的是“捕获”文件未找到错误,并将另一个文件发送回调用应用程序。类似于您如何在网络服务器上处理 404 错误并根据所请求的 URL 返回某些内容,但在本地文件系统上除外。
这可能吗?更可取的是,在.Net 中是否可行?
我有一个在目录中查找文件的旧应用程序。它不能很好地处理丢失的文件。我想要做的是“捕获”文件未找到错误,并将另一个文件发送回调用应用程序。类似于您如何在网络服务器上处理 404 错误并根据所请求的 URL 返回某些内容,但在本地文件系统上除外。
这可能吗?更可取的是,在.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 注入都可以帮助您。
Microsoft 有可以帮助你的Detours包,CodePlex 有看起来很有趣的EasyHook 。