软盘君
本站的沙雕站长,半吊子运维
Floppy β Studio

修复管理员身份运行的程序无法从资源管理器拖放(ChangeWindowMessageFilter)

修复管理员身份运行的程序无法从资源管理器拖放(ChangeWindowMessageFilter)

为什么会出现无法拖放

条件:你的Windows版本>=NT6.0,你以普通用户的身份运行了Windows外壳程序(Windows资源管理器),又以管理员身份运行了test.exe,test.exe是一个包含了拖放对象的Windows窗体程序

发生的问题:不能够把任何东西从资源管理器拖放到test.exe

原因:你没有将UAC彻底关闭

原理:低权限的进程是无法向高权限的进程发送任何高于 WM_USER 的消息,而低于 WM_USER 的消息一部分也会因为安全原因被禁止。

我应该如何解决这个问题

从用户的角度,有两种方式(不建议从用户的角度这么做,因为在Win10下会发生一些花里胡哨的BUG,Win8.x下会禁止你使用metro应用)

1 停用这个机制(修改注册表)脚本:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem]

“ConsentPromptBehaviorAdmin”=dword:00000000

“EnableLUA”=dword:00000000

“PromptOnSecureDesktop”=dword:00000000

2 以管理员身份运行资源管理器(和上一个方法差不多)

从开发者的角度(推荐,不会发生过多的BUG),我们可以通过API来解决:ChangeWindowMessageFilter(Ex)

建议带上Ex,因为ChangeWindowMessageFilter面向的是整个进程,ChangeWindowMessageFilterEx是只对窗口进行应用

在C/C++中的用法:(在哪个头文件自己看MSDN)

ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD); 

ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD); 

ChangeWindowMessageFilter(WM_COPYGLOBALDATA , MSGFLT_ADD);

引用阿毛的文章某一部分:其中 WM_COPYGLOBALDATA 在 winodws.h 中并没有相应的定义,也可以直接用它的数值 0×0049 来代替。至于为啥要这么做,并没有很明确的官方文档说明,不过也可以猜出个大概:WM_COPYDATA 和 WM_COPYGLOBALDATA 是用于 explorer.exe 和当前进程进行进程通信的消息。

易语言下处理这个问题

DLL命令表:

.版本 2

.DLL命令 SetWindowLong, 整数型, “user32.dll”, “SetWindowLongA”
.参数 hWnd, 整数型
.参数 nIndex, 整数型
.参数 dwNewLong, 整数型

.DLL命令 CallWindowProc, 整数型, “user32.dll”, “CallWindowProcA”
.参数 lpPrevWndFunc, 整数型
.参数 hWnd, 整数型
.参数 Msg, 整数型
.参数 wParam, 整数型
.参数 lParam, 整数型

.DLL命令 GetVersion, 整数型, “kernel32.dll”, “GetVersion”

.DLL命令 ChangeWindowMessageFilter, 逻辑型, “user32.dll”, “ChangeWindowMessageFilter”
.参数 message, 整数型
.参数 dwFlag, 整数型

.DLL命令 DragAcceptFiles, , “shell32.dll”, “DragAcceptFiles”
.参数 hWnd, 整数型
.参数 fAccept, 逻辑型

.DLL命令 DragQueryPoint, 逻辑型, “shell32.dll”, “DragQueryPoint”
.参数 hDrop, 整数型
.参数 lppt, POINT, 传址

.DLL命令 DragQueryFile, 整数型, “shell32.dll”, “DragQueryFileA”
.参数 hDrop, 整数型
.参数 iFile, 整数型
.参数 lpszFile, 文本型, 传址
.参数 cch, 整数型

.DLL命令 DragFinish, , “shell32.dll”, “DragFinish”
.参数 hDrop, 整数型

声明一个变量:

.版本 2

.程序集变量 lpPrevWndFunc, 整数型

在窗口创建完毕之后,加上代码:

.版本 2

lpPrevWndFunc = SetWindowLong (取窗口句柄 (), -4, 到整数 (&WndProc))  ‘ 更换消息处理程序

DragAcceptFiles (取窗口句柄 (), 真)  ‘ 允许窗口拖放

ChangeWindowMessageFilter (#WM_COPYGLOBALDATA, #MSGFLT_ADD)

ChangeWindowMessageFilter (#WM_DROPFILES, #MSGFLT_ADD)

更换消息处理程序的时候哪个子程序在这里:

.版本 2

.子程序 WndProc, 整数型
.参数 hWnd, 整数型
.参数 Msg, 整数型
.参数 wParam, 整数型
.参数 lParam, 整数型
.局部变量 Point, POINT
.局部变量 FileNumber, 整数型
.局部变量 FileName, 文本型
.局部变量 FileNameLength, 整数型
.局部变量 i, 整数型

.如果真 (Msg = #WM_DROPFILES)
‘ DragQueryPoint (wParam, Point) ‘ 取文件放入窗口时的坐标
FileNumber = DragQueryFile (wParam, 4294967295, “”, 0) ‘ 取拖放文件数量
.变量循环首 (0, FileNumber - 1, 1, i)
FileNameLength = DragQueryFile (wParam, i, “”, 0) ‘ 取拖放文件名长度
.如果真 (FileNameLength ≠ 0)
FileName = 取空白文本 (FileNameLength)
DragQueryFile (wParam, i, FileName, FileNameLength + 1) ‘ 取拖放文件名
信息框 (FileName, 0, )

.如果真结束

.变量循环尾 ()
DragFinish (wParam) ‘ 拖放完毕
.如果真结束
返回 (CallWindowProc (lpPrevWndFunc, hWnd, Msg, wParam, lParam))

这个封装好了的回调函数的功能是弹出一个信息框,里面显示你拖放的文件(自己改)

本文章(修复管理员身份运行的程序无法从资源管理器拖放(ChangeWindowMessageFilter))使用CC BY-SA 3.0进行许可,转载请注明出处: 如果你认为我们的文章对您有帮助,请在Youtube订阅软盘君的频道

华为云优惠!

没有标签
首页      经验      修复管理员身份运行的程序无法从资源管理器拖放(ChangeWindowMessageFilter)
Floppy

Floppy

文章作者

生命不息,折腾不止~这是一个沙雕博主,不务正业的那种,还喜欢瞎折腾~

推荐文章

你需要先 登录 才能发表评论。

Floppy β Studio

修复管理员身份运行的程序无法从资源管理器拖放(ChangeWindowMessageFilter)
为什么会出现无法拖放 条件:你的Windows版本>=NT6.0,你以普通用户的身份运行了Windows外壳程序(Windows资源管理器),又以管理员身份运行了test.exe,test.exe是一个包含了拖放对…
扫描二维码继续阅读
2019-07-25