解决Win7及以后以管理员权限运行的程序无法收到 WM_DROPFILES 消息的问题

那还是在很早很早之前,就发现过一个奇怪的问题:Win7及以后的系统上(源于Vista),以管理员权限运行的命令提示符无法通过从资源管理器拖放文件的形式获取文件路径。

Windows的命令提示符本来就极其难用了,还tm有这种feature,真无语。

然而今天在写GUI程序时也遇到这样的问题了。

在非管理员模式下,能通过拖放拿到文件。但在管理员模式下时,拿不到,甚至连 WM_DROPFILES 消息都收不到。

通过搜索,了解到以下一些原因:

Drag and Drop File into Application under run as administrator

Your drag'n'drop isn't working for permissions levels differences, if the other program/explorer you're dragging from is not elevated as administrator Windows is smart enough to not let the user do that.

Can't drag and drop when 'run as administrator'

The problem is tied to how security permissions work. The ability to drag and drop from a normal applications to an elevated one would break the security model behind UAC. However, I'm unclear as to why a UAC prompt isn't shown, thus allowing for a temporary elevated operation (much like any linux user experiences every day). This is definitely something that Microsoft needs to work on. What troubles me is that this problem is already old. Vista behaved the same.

There's 2 things you can do (one ugly, one annoying)

    Ugly: Disable UAC. But you lose all the extra security it offers.
    Annoying: Use another File manager and run it too as an Administrator

Why another file manager? Because you can't actually elevate Windows Explorer. Despite seeing the option in the context menu of the Windows Explorer icon and a UAC prompt being displayed, the fact is Windows Explorer will not be elevated.

一言以蔽之就是:因为 UIPI 的原因,低权限的进程不能向高权限的进程发送消息。我这里就是:资源管理器向我的以管理员权限运行的程序发消息,将失败。

然而我还发现另一个问题:QQ影音在以管理员权限运行时,仍然可以支持拖放。所以我猜测估计又用了什么奇技淫巧。果然,通过文章“简单方法解决Vista/Win7 无法接收WM_DROPFILES问题”了解到,加上以下代码就可以恢复使用拖放功能的使用:

ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
ChangeWindowMessageFilter(0x49 /* WM_COPYGLOBALDATA */, MSGFLT_ADD);

可以轻易得出一个不很确定的结论:消息其实是收到的,只是被 user32 模块给简单地过滤掉了。M$的把戏真多。

另外,从 HwangBae 那了解到:这种解决办法不总是有效,请看聊天记录。

附上一些聊天记录:

【传说】女孩不哭(191035066) 23:41:36 PM
@MeeSong 我发现我自己写的程序,在管理员模式下,也无法使用拖放。
【传说】女孩不哭(191035066) 23:42:17 PM
[图片]
全部是这个消息。
【话唠】蓝灵侠武(374397721) 23:43:07 PM
你用啥写的
【传说】女孩不哭(191035066) 23:43:24 PM
废话
【话唠】蓝灵侠武(374397721) 23:44:48 PM
win32 的话 
【话唠】蓝灵侠武(374397721) 23:44:53 PM
响应这个消息
【话唠】蓝灵侠武(374397721) 23:44:54 PM
WM_DROPFILES
【传说】女孩不哭(191035066) 23:45:14 PM
重点不是消息,是管理员模式。
【传说】女孩不哭(191035066) 23:47:24 PM
[图片]
三种UAC。
【话唠】蓝灵侠武(374397721) 23:47:36 PM
是我误解你的意思了么  你说的不是文件拖放到窗口么
【传说】女孩不哭(191035066) 23:48:09 PM
“我发现我自己写的程序,在管理员模式下,也无法使用拖放。”
还有一个重点:也。
说明是有上下文的。双击查看原图
【传说】女孩不哭(191035066) 23:49:34 PM
[图片]
【话唠】蓝灵侠武(374397721) 23:51:09 PM
cmd就不清楚了
【传说】女孩不哭(191035066) 23:54:20 PM
非cmd也不行啊,交流真困难。别欺负我只是初中毕业啊。
【话唠】蓝灵侠武(374397721) 23:57:46 PM
自己写的窗口程序肯定是可以的
【话唠】蓝灵侠武(374397721) 23:57:53 PM
除非你的是控制台
【传说】女孩不哭(191035066) 23:58:10 PM
[表情]你真的试过吗。
【话唠】蓝灵侠武(374397721) 23:59:05 PM
我之前写过一个有拖放文件的程序
【话唠】蓝灵侠武(374397721) 23:59:17 PM
人家win10的 用了 也是可以的
【传说】女孩不哭(191035066) 23:59:45 PM
[图片]
现在就是 Not Allowed,代表以管理员运行的。但现在是无法拖放的,收不到消息。
	2016-01-30	
【传说】女孩不哭(191035066) 0:02:07 AM
[图片]
然而它却可以。
【话唠】蓝灵侠武(374397721) 0:02:58 AM
那说明你写的逻辑有问题
【传说】女孩不哭(191035066) 0:03:20 AM
消息都没收到,哪来的逻辑啊。
【话唠】蓝灵侠武(374397721) 0:06:54 AM
你发来我试试
【传说】女孩不哭(191035066) 0:08:55 AM
不方便发代码。先搜搜看。。。
【传说】女孩不哭(191035066) 0:20:29 AM
[图片]
【传说】女孩不哭(191035066) 0:30:26 AM
Your drag'n'drop isn't working for permissions levels differences, if the other program/explorer you're dragging from is not elevated as administrator Windows is smart enough to not let the user do that.
【活跃】『月夜』<3.vc@163.com> 0:31:39 AM
管理员模式不行的
【活跃】『月夜』<3.vc@163.com> 0:32:21 AM
MESSAGE是SESSION隔离的
【传说】女孩不哭(191035066) 0:32:45 AM
然而QQ影音可以。
【活跃】『月夜』<3.vc@163.com> 0:33:06 AM
QQ影音管理员模式吗
【传说】女孩不哭(191035066) 0:33:13 AM
我和程序和QQ影音都是 “Not Allowed”。
【传说】女孩不哭(191035066) 0:33:30 AM
都是,都是以管理员权限运行。
【传说】女孩不哭(191035066) 0:34:19 AM
难道又是使用了什么奇技淫巧。
【活跃】『月夜』<3.vc@163.com> 0:37:05 AM
http://blog.sina.com.cn/s/blog_6294abe70101bko6.html
【传说】女孩不哭(191035066) 0:39:52 AM
试试看。
【话唠】蓝灵侠武(374397721) 0:40:35 AM
为什么我没有这个问题
【传说】女孩不哭(191035066) 0:41:58 AM
我人品问题。
【传说】女孩不哭(191035066) 0:45:13 AM
[图片]
【传说】女孩不哭(191035066) 0:46:50 AM
@『月夜』 可行。
【传说】女孩不哭(191035066) 0:47:17 AM
所以,M$又耍了个花招。
【传说】女孩不哭(191035066) 0:47:40 AM
能收到,只是被极其简单地过滤掉了。
【吐槽】HwangBae(378094471) 0:47:43 AM
win7开始最好用带ex的版本,并且这种方法对于OLE drag drop不管用。这是系统的UIPI机制。
【传说】女孩不哭(191035066) 0:48:53 AM
第1次用。
【活跃】『月夜』<3.vc@163.com> 0:49:02 AM
[表情]
发表于:2016年1月30日,阅读量:245,标签:WinAPI