0

There are several sources explaining the UAC thing that prevents dragging and dropping files from the explorer onto your elevated application, but none of them covers a WPF example.

The problem is that my application NEEDS to be run with administrator rights, but at the same time it clashes with the problem above, so I'm in a deadlock.

For reference, there's this link showing how this would be solved within a MFC application (which is not the case), using the ChangeWindowMessageFilter API.

Is it possible to achieve the same thing within a WPF application?

- UPDATE -

Things I have tried:

  1. Calling ChangeWindowMessageFilter after my main window's handle was created. The function returns true.
  2. Calling ChangeWindowMessageFilterEx after my main window's handle was created, passing it as param. The function returns true and the CHANGEFILTERSTRUCT.ExtStatus is MSGFLTINFO_NONE.
  3. Calling DragAcceptFiles after my main window's handle was created, DragQueryFile and DragFinish, however it looks like the DragAcceptFiles call isn't allowing dragging events (WM_DROPFILES) under WndProc, as follows:

.

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;
    }
}
Yves Calaci
  • 1,019
  • 1
  • 11
  • 37
  • 1
    https://stackoverflow.com/questions/8239271/uac-elevation-does-not-allow-drag-and-drop – Hans Passant May 21 '19 at 05:05
  • 2
    Whether you use Win32, MFC, WPF, etc, the solution is still the same - you must call `ChangeWindowMessageFilter/Ex()` in the elevated process to allow it to receive drag&drop messages from unelevated processes. – Remy Lebeau May 21 '19 at 07:22
  • @HansPassant sorry, what?! Could you elaborate on your reply? Are you saying it's not possible unless you either modify the manifest's uiAccess to true (which didn't solve the problem btw), store my EXE into the `c:\windows`/`c:\program files` subdirectories and/or sign my application with certificate from an valid code signing authority? What about Remy's answer? – Yves Calaci May 21 '19 at 12:46
  • @RemyLebeau I'm aware that the `ChangeWindowMessageFilter` API is the way to go. If this is all the same, could you tell me where the `ChangeWindowMessageFilter/Ex` should be called? Within the control's constructor? Loaded event callback (if any)? Within the owner window's constructor? Etc. Btw you have been helping me secretly since the good times of Borland C++ Builder :) – Yves Calaci May 21 '19 at 12:58
  • I merely pointed you to the exact same question. That its conclusion is inconvenient does not change the outcome, you can't do it. – Hans Passant May 21 '19 at 13:31
  • @Henri `ChangeWindowMessageFilterEx` is per-window, so call it when the target control's window becomes available. I'm not a WPF dev, so I couldn't tell you exactly where the best place to detect that is, refer to MSDN for documentation. Otherwise, `ChangeWindowMessageFilter` is process-wide, it affects all windows, so you can call it at app startup, even before the target control is created. – Remy Lebeau May 21 '19 at 16:08
  • @RemyLebeau I've updated my post. – Yves Calaci May 21 '19 at 16:27
  • 1
    I see no call to `ChangeWindowMessageFilterEx()` in the code you have shown. Have you tried putting it in your `OnSourceInitialized()` right above the call to `DragAcceptFiles()`? And BTW, `WM_DROPFILES` is long deprecated, you really should implement the `IDropTarget` interface on the window instead. But how you do that with WPF, I have no clue. – Remy Lebeau May 21 '19 at 19:11
  • The snippet is covering only the last attempt, which is the third item from the list. Someone claims that he accomplished the above by implementing the `IDropTarget`. I'll try it out and come back later. – Yves Calaci May 21 '19 at 19:30

1 Answers1

0
"The problem is that my application NEEDS to be run with administrator rights". 

Correct. The problem is that your application is not well designed if the UI needs elevated privileges. The UI should always run under standard user account privileges. If you need elevated privileges, use a Windows service. Then use an IPC mechanism to communicate between the UI and the service, named pipes, for example.

Alexandru Dicu
  • 1,151
  • 1
  • 16
  • 24