Моя программа захватывает, когда USB-устройства подключены / отключены, и делает то, что должно делать.
Есть одна неприятная вещь: проводник открывает окно. Угадай, что виновата автоматическая игра. Полное отключение автовоспроизведения на этой машине не является вариантом, поэтому его нужно отключать только тогда, когда это приложение запущено.
Я нашел множество статей о том, как это сделать, перехватив сообщение Windows. Это позволяет использовать следующий код, который компилируется и запускается при поступлении сообщений windows. Но, к сожалению, QUeryCancelAutoPlay, похоже, никогда не вызывается.
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}
private UInt32 queryCancelAutoPlay = 0;
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (queryCancelAutoPlay == 0)
{
queryCancelAutoPlay = RegisterWindowMessage("QueryCancelAutoPlay");
}
if (msg == queryCancelAutoPlay)
{
return (IntPtr)1;
}
return IntPtr.Zero;
}
Есть предположения ? Я разрабатываю это на машине win10.
public partial class MainWindow : NavigationWindow
{
public int queryCancelAutoPlay = 0;
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int RegisterWindowMessage(string lpString);
public MainWindow()
{
InitializeComponent();
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
MainWindow_Closing(this, e);
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
MainWindow_SourceInitialized(this, e);
}
private void MainWindow_SourceInitialized(object sender, EventArgs e)
{
Debug.WriteLine("Initialize MainWindow");
IntPtr windowHandle = (new WindowInteropHelper(this)).Handle;
HwndSource src = HwndSource.FromHwnd(windowHandle);
src.AddHook((WndProc));
}
private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
//if the QueryCancelAutoPlay message id has not been registered...
if (queryCancelAutoPlay == 0)
{
queryCancelAutoPlay = RegisterWindowMessage("QueryCancelAutoPlay");
Debug.WriteLine("cancel autoplay registered. msg id: " + queryCancelAutoPlay.ToString());
}
//if the window message id equals the QueryCancelAutoPlay message id
if (msg == queryCancelAutoPlay)
{
Debug.WriteLine("Autoplay cancelled");
queryCancelAutoPlay = 0;
handled = true;
return new IntPtr(1);
}
return new IntPtr(msg);
}
private void MainWindow_Closing(object sender, CancelEventArgs e)
{
Debug.WriteLine("Close MainWindow");
HwndSource source = (HwndSource)HwndSource.FromVisual(this);
source.RemoveHook(new HwndSourceHook(this.WndProc));
}
}
Кажется или правда никогда не назывался? Попробуйте добавить перерыв в отладке. Кроме того, приложение должно находиться в верхнем окне, иначе оно не получит сообщения. Я сам боролся с отменой события автовоспроизведения в функции WndProc. Моим решением было добавить handled = true; непосредственно перед возвратом (IntPtr) 1