1

我想编写一个自定义的另存为对话框,该对话框连接到大多数 Windows 程序的文件 - >“另存为”。此自定义对话框将允许用户输入他们的用户名、密码、目标文件夹并通过 POST 将文件上传到 Web 服务器。如果用户单击取消,它将调用原始文件对话框。

我一直在阅读有关 Windows API 挂钩的信息,这模糊地是我认为我会如何处理这个问题:

  1. 拦截“另存为”
  2. 显示我的自定义对话框,返回驱动器上的一些临时路径
  3. 让程序将文件写入临时路径,假设它现在调用 WINAPI CreateFile(...)
  4. 读取临时文件并上传到网络服务器
  5. 清理临时文件

但我仍然无法理解实现这一目标所需的步骤。假设我可以拦截“另存为”和 CreateFile 函数,我如何检测 CreateFile 是从“另存为”调用的,而不仅仅是任何随机文件创建?我可以想到一个技巧,我可以跟踪打开文件对话框和调用 CreateFile 的时间差。

我的替代解决方案是使用现有的文件对话框并在磁盘上创建一个特殊的文件夹,该文件夹会受到持续监控。当一个文件被写入那里时,它将调用一个上传文件的外部程序。我还没有研究如何做到这一点。我怀疑这更容易。

更新

作为第一步,我编写了一个 .NET 任务托盘应用程序,它允许用户输入他们的登录详细信息和一个要监视的文件夹。每当一个文件被放在那里时,它都会上传到网络服务器。到目前为止,它似乎工作。现在我只需要弄清楚如何在文件对话框的左窗格中添加一个不错的快捷方式。一旦完成,我想我得到了一个我满意的解决方案。

4

2 回答 2

2

无需挂钩或修补任何东西。IStorage::CreateStream创建一个外壳命名空间扩展,通过返回一个将其数据发布到 Web 服务器的流来支持和实现它。然后,用户可以选择将文件保存到您的命名空间扩展名以上传文件。

于 2012-10-19T03:58:52.563 回答
1

挂钩标准保存对话框需要您将 DLL 注入每个正在运行的进程,并让它替换GetSaveFileName()进程 PE 标头中 Win32 API 函数的导入存根(防病毒和反恶意软件应用程序不太可能对此感到满意) )。

然后是在 Vista 中引入的新型保存对话框,它使用新的IFileSaveDialogCOM 接口而不是GetSaveFileName(). 为此,您必须卸载 Microsoft 的默认 FileDialog COM 对象并将其替换为自定义实现。

这不包括定制的保存对话框,您不太可能挂钩。

如果奇迹般地,您可以挂钩对话框并让它返回您自己创建的自定义路径,您不需要挂钩CreateFile()自己,只需监控您为您的目的创建的文件夹。将其放置在除您之外的任何其他应用程序(或用户)不太可能向其写入文件的位置。为此,您可以在用户或系统的文件夹中创建自定义子AppData文件夹。您可以使用SHGetSpecialFolderPath()和/或SHGetKnownFolderPath()查找这些文件夹。

棘手的部分将是检测文件何时完成写入并已关闭。您将必须监视文件夹的更改,例如使用ReadDirectoryChangesW()or SHChangeNotifyRegister(),并定期打开新的/修改的文件以进行独占访问。如果文件仍被其他人打开,您将无法自己打开它。但是一旦你打开它,你可以用它做任何你想做的事情。

于 2012-10-19T02:49:45.217 回答