您如何检测文件何时被放入 Windows 资源管理器?

Posted

技术标签:

【中文标题】您如何检测文件何时被放入 Windows 资源管理器?【英文标题】:How can you detect when files are dropped into Windows Explorer? 【发布时间】:2010-11-08 14:20:55 【问题描述】:

我有一个带有 TreeView 的 WinForms 应用程序。用户可以将文件从 WindowsExplorer 拖到 TreeView,然后他们可以将文件拖回 WindowsExplorer,这实际上会将文件复制到文件所在的位置。我想要做的是,如果文件已经存在于文件被删除的目录中,我想提前重命名正在复制的文件/文件夹,这样就不会发生冲突。

以下是我将文件复制到 WindowsExplorer 的方法。在 treeView 的 ItemDrag 上,我循环遍历所选节点的节点,然后将其打包成一个数组。然后,我使用以下代码:

        var dataObject = new DataObject(DataFormats.FileDrop, files.ToArray());
        dataObject.SetData(DataFormats.StringFormat, dataObject);
        DoDragDrop(dataObject, DragDropEffects.Copy);

这很好用,但是一旦发送到 Windows 资源管理器,我就无法控制它了。如何找出文件被复制到的时间和位置并拦截以进行更改?这可能吗?

【问题讨论】:

您想查看这篇文章 - codeproject.com/KB/shell/explorerdragdrop.aspx - 了解 C++ 的执行方式。这可能会有所帮助。 【参考方案1】:

Explorer Drag & Drop 是一篇出色的文章,可以实现您正在努力实现的目标。

EDIT2:在 CodeProject 上似乎有一个 C++ article 可用。但是我找不到使用 C# 的方法。

【讨论】:

这并没有涵盖我遇到的主要问题。如果您尝试从他的示例中的列表框拖回资源管理器,您会像往常一样收到窗口提示。我想避免这种情况,并自动重命名文件。【参考方案2】:

AFAIK,无法知道放置目标(在您的情况下为目标文件夹)。您可以查看CFSTR_FILENAMEMAP shell 剪贴板格式,但在这种情况下,您仍然只能在拖放之前(或正在进行中)提供名称映射。

另请注意,.net 中的默认 DataObject 具有有限的 shell 支持。所以如果你需要使用上面提到的格式,你需要编写自己的IDataObject实现(或者拿别人的实现,很多shell拖放相关的好例子可以找到here)

【讨论】:

【参考方案3】:

不要将文件名放入数据对象中,而是创建一个具有唯一/易于区分名称的临时文件,并将该文件名放入数据对象的下拉列表中(该文件可能为空或包含您可能需要的一些信息) .使用 FileSystemWatcher(监视整个驱动器)来检测 drop(将过滤器设置为临时文件名,将 IncludeSubDirectories 设置为 true,并将 Path 设置为要监视的驱动器的根目录。)启动 DoDragDrop。一旦唯一/易于区分的文件被删除,FileSystemWatcher 可以告诉您它被删除的位置,您可以做任何您需要做的事情(例如删除删除的临时文件并替换为您最初想要删除的文件。这是一个很远-from-perfect 解决方案,但可能会有所帮助。更好的是,它可能会让某人想到一个更好的解决方案!)

一个缺点是您并不真正知道有人可能会将文件放在哪个驱动器中,并且您可能必须为多个驱动器设置一个观察程序。如果您错过了驱动器(或网络路径),那么问题......!记得在 drop 后处理掉观察者。

但必须有更好的方法。例如考虑从 zip 文件夹中拖动文件时。该文件仅在放置后提取。

【讨论】:

【参考方案4】:

我认为这是不可能的。

【讨论】:

以上是关于您如何检测文件何时被放入 Windows 资源管理器?的主要内容,如果未能解决你的问题,请参考以下文章

Windows Azure 服务总线队列重复检测如何工作?

检测屏幕何时锁定 UWP

检测文件何时被拖到文件输入

Android webview如何检测何时重新加载

如何从 Windows 应用程序检测禁用的网络接口连接?

如何检测文件的使用权限 (DRM)