Задать вопрос
@hax
junior developer

Как корректно получить handle консольного приложения?

Пишу приложение, которое отслеживает подключаемые флешки в компьютер. Использую WinApi'шную библиотеку User32.dll для регистрации эвентов.
Сейчас имееется такая заготовка:
public class Win32
{
    ...

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr RegisterDeviceNotification(IntPtr IntPtr, IntPtr NotificationFilter, Int32 Flags);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern uint UnregisterDeviceNotification(IntPtr hHandle);

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string className, string lpWindowName);
    
    ...
}

private static void RegisterDeviceNotification()
    {
        Win32.ServiceControlHandlerEx myCallback = new Win32.ServiceControlHandlerEx(ServiceControlHandler);
        Win32.RegisterServiceCtrlHandlerEx(Process.GetCurrentProcess().ProcessName, myCallback, IntPtr.Zero);

        var serviceHandler = FindWindow(null, Console.Title);
        // serviceHandler = Process.GetCurrentProcess().Handle;
        // serviceHandler = Process.GetCurrentProcess().MainWindowHandle;

        if (serviceHandler == IntPtr.Zero)
        {
            throw new Exception();
        }

        Win32.DEV_BROADCAST_DEVICEINTERFACE deviceInterface = new Win32.DEV_BROADCAST_DEVICEINTERFACE();
        int size = Marshal.SizeOf(deviceInterface);
        deviceInterface.dbcc_size = size;
        deviceInterface.dbcc_devicetype = Win32.DBT_DEVTYP_DEVICEINTERFACE;
        IntPtr buffer = default(IntPtr);
        buffer = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(deviceInterface, buffer, true);
        deviceEventHandle = Win32.RegisterDeviceNotification(serviceHandler, buffer,
                                                             Win32.DEVICE_NOTIFY_SERVICE_HANDLE |
                                                             Win32.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
        if (deviceEventHandle == IntPtr.Zero)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error()); 
        }
    }


GetLastWin32Error выдают ошибку - The handle is invalid. В чем моя ошибка? И как правильно нужно получить handle консольного приложения?
  • Вопрос задан
  • 393 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 2
https://docs.microsoft.com/en-us/windows/console/g...
В чем моя ошибка?

Вы решили, что консольное приложение имеет окно в понятиях WinAPI. Это не так.
Ответ написан
Комментировать
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
Дополнение к ответу выше:

RegisterDeviceNotification function
Parameters
hRecipient [in]
A handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter. The same window handle can be used in multiple calls to RegisterDeviceNotification.

Services can specify either a window handle or service status handle.

[...]

Remarks:
Any application with a top-level window can receive basic notifications by processing the WM_DEVICECHANGE message. Applications can use the RegisterDeviceNotification function to register to receive device notifications.

Services can use the RegisterDeviceNotification function to register to receive device notifications. If a service specifies a window handle in the hRecipient parameter, the notifications are sent to the window procedure. If hRecipient is a service status handle, SERVICE_CONTROL_DEVICEEVENT notifications are sent to the service control handler.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы