Drag&Drop в WPF-приложении при запуске от Администратора

Приветствую!
Имеется WPF-приложение с поддержкой Drag&Drop. Перетаскиваешь файл на окно приложения - оно получает путь в нему.
Но, при запуске от имени администратора Drag&Drop не работает. Microsoft сделала это для предотвращения засылки данных из непривилегированного процесса в привилегированный.
Известно и решение - принудительное включение обработки соответствующих сообщений при помощи функций ChangeWindowMessageFilter/ChangeWindowMessageFilterEx.

ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ALLOW);
ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ALLOW);
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ALLOW);

DragAcceptFiles(hWnd, TRUE);

И надо сказать этот способ работает в приложении, написанном на WinAPI.
Но, в приложении WPF данный способ категорически не хочет работать. Обработчики сообщений WM_COPYDATA, WM_COPYGLOBALDATA и WM_DROPFILES категорически не хотят включаться.

protected override void OnSourceInitialized(EventArgs e)
{
	base.OnSourceInitialized(e);
	HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
	source.AddHook(WndProc);

	ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ALLOW);
	ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ALLOW);
	ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ALLOW);

	DragAcceptFiles(source.Handle, true);
}

private IntPtr WndProc(IntPtr Hwnd, Int32 Msg, IntPtr wParam, IntPtr lParam, ref Boolean Handled)
{
	switch (Msg)
	{
		case WM_COPYDATA:
			MessageBox.Show("WM_COPYDATA");
			break;

		case WM_COPYGLOBALDATA:
			MessageBox.Show("WM_COPYGLOBALDATA");
			break;

		case WM_DROPFILES:
			MessageBox.Show("WM_DROPFILES");
			break;

		case 0x2://WM_DESTROY
			MessageBox.Show("WM_DESTROY");
			break;

		case 0x18://WM_SHOWWINDOW
			DragAcceptFiles(Hwnd, true);
			MessageBox.Show("WM_SHOWWINDOW");
			break;
	}

	return IntPtr.Zero;
}

Другие сообщения обрабатываются. Для примера взял WM_DESTROY и WM_SHOWWINDOW.

Кто-нибудь знает, как заставить работать Drag&Drop в WPF под администратором?

Похоже тут дело не только в WPF.
winapi - How can I send WM_DROPFILES from C#? - Stack Overflow

WM_DROPFILES has been deprecated ever since DoDragDrop() was introduced way back in Windows 95. OLE Drag&Drop has been the preferred way to implement drag&drop on Windows for a very long time. WM_DROPFILES is still supported by Windows (but not .NET) but only for backwards compatibility with legacy apps.

Так что если нет каких-то оф. способов убрать это, то видимо только придумывать какие-то другие варианты работы типа буфера обмена, переноса админских действий в другой процесс или всяких извращений.

Так я же это принудительно включаю вызовом WinAPI функции ChangeWindowMessageFilter

А она что возвращает?

TRUE if successful; otherwise, FALSE . To get extended error information, call GetLastError.

Возвращает TRUE для всех трех сообщений WM_COPYDATA, WM_COPYGLOBALDATA и WM_DROPFILES.

Отключите UAC.
Может быть логику приложения нужно изменить?? Зачем вам нужно запускать софт от имени админа*?? Он делает что то важное с системой??

Он загружает/выгружает драйвера. Без админских привилегий никак.

Такое же приложение, написанное на WinAPI на С спокойно работает без отключения UAC.
Осталось понять, в чем загвоздка в WPF :slight_smile: