【发布时间】:2019-10-07 09:27:58
【问题描述】:
有几个来源解释了防止将文件从资源管理器拖放到提升的应用程序的 UAC 问题,但没有一个涵盖 WPF 示例。
问题是我的应用程序需要以管理员权限运行,但同时它与上面的问题冲突,所以我陷入了僵局。
作为参考,this link 展示了如何使用 ChangeWindowMessageFilter API 在 MFC 应用程序中解决此问题(并非如此)。
是否可以在 WPF 应用程序中实现相同的功能?
- 更新-
我尝试过的事情:
- 在创建主窗口句柄后调用
ChangeWindowMessageFilter。该函数返回 true。 - 在创建主窗口句柄后调用
ChangeWindowMessageFilterEx,将其作为参数传递。该函数返回 true,CHANGEFILTERSTRUCT.ExtStatus为MSGFLTINFO_NONE。 - 在我的主窗口句柄创建后调用
DragAcceptFilesDragQueryFile和DragFinish,但是看起来DragAcceptFiles调用不允许在WndProc下拖动事件(WM_DROPFILES),如下:
.
public partial class MainWindow : Window
{
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
var source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
WinAPI.DragAcceptFiles(new WindowInteropHelper(this).Handle, true);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WinAPI.WM_DROPFILES)
{
// Not reaching here
}
return IntPtr.Zero;
}
}
【问题讨论】:
-
无论你使用Win32、MFC、WPF等,解决方法都是一样的——你必须在提升的进程中调用
ChangeWindowMessageFilter/Ex(),让它接收来自非提升进程的拖放消息。 -
@HansPassant 对不起,什么?!你能详细说明你的回复吗?您是说这是不可能的,除非您将清单的 uiAccess 修改为 true(顺便说一句,这并没有解决问题),将我的 EXE 存储到
c:\windows/c:\program files子目录和/或使用来自有效证书的证书签署我的应用程序代码签名权限?雷米的回答呢? -
@RemyLebeau 我知道
ChangeWindowMessageFilterAPI 是要走的路。如果这都是一样的,你能告诉我应该在哪里调用ChangeWindowMessageFilter/Ex吗?在控件的构造函数中?加载事件回调(如果有)?在所有者窗口的构造函数中?等等。顺便说一句,自从 Borland C++ Builder 的好时光以来,你一直在秘密地帮助我 :) -
我在您显示的代码中没有看到对
ChangeWindowMessageFilterEx()的调用。你有没有试过把它放在你的OnSourceInitialized()就在DragAcceptFiles()的调用上方?顺便说一句,WM_DROPFILES早已被弃用,你真的应该在窗口上实现IDropTarget接口。但是你如何用 WPF 做到这一点,我不知道。
标签: c# winapi drag-and-drop uac uipi