使用C ++检测Windows插入/删除事件 [英] Detecting USB Insertion / Removal Events in Windows using C++

查看:218
本文介绍了使用C ++检测Windows插入/删除事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为需要处理USB插入/移除事件的现有应用程序编写扩展。我知道感兴趣的设备的VID / PID。但是,我没有访问窗口句柄,所以我不知道如果 RegisterDeviceNotification 将是很有用的,除非有办法获取句柄通过 WINAPI 。使用C ++检测USB插入/删除事件的最佳方式是什么?

I am writing an extension for an existing application that needs to handle USB insertion/removal events. I know the VID/PID of the device of interest. However, I don't have access to the window handle, so I don't know if RegisterDeviceNotification will be of much use, unless there is a way to obtain the handle via the WINAPI. What would be the best way to detect USB insertion/removal events with C++?

Microsoft网站上的此示例代码显示了如何通过WMI接收事件通知:

This sample code on the Microsoft website shows how to receive event notifications via WMI:

如何修改以接收USB插入/删除事件?或者,还有另一种方式我应该去做这件事吗?我正在使用Visual Studio 2008.谢谢。

How could it be modified to receive USB insertion/removal events? Or, is there another way I should be going about this? I am using Visual Studio 2008. Thanks.

其他信息

ADDITIONAL INFO

这是我到目前为止(减去错误处理):

This is what I have so far (minus error-handling):

DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, 0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);

MyClass::MyClass()
{
    // Generate message-only window
    _pWndClassEx = (WNDCLASSEX *)malloc( sizeof(WNDCLASSEX) );
    memset( _pWndClassEx, 0, sizeof(WNDCLASSEX) );
    _pWndClassEx->cbSize = sizeof(WNDCLASSEX);
    _pWndClassEx->lpfnWndProc = (WNDPROC)WndProc; // function which will handle messages
    _pWndClassEx->hInstance = GetCurrentModule();
    _pWndClassEx->lpszClassName = pClassName;
    atom = RegisterClassEx( _pWndClassEx );
    _hWnd = CreateWindowEx( 0, pClassName, pWindowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );

    // Register the USB device for notification
    _pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    _pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    _pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    _pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
    _hNotifyDevNode = RegisterDeviceNotification( _hWnd, _pDevIF, DEVICE_NOTIFY_WINDOW_HANDLE );
}

static bool OnDeviceChange(UINT nEventType, DWORD dwData)
{
    switch ( nEventType )
    {
    case DBT_DEVICEARRIVAL:
        // A device has been inserted adn is now available.
        break;

    case DBT_DEVICEREMOVECOMPLETE:
        // Device has been removed.
        break;

    default:
        break;
    }

    return true;
}

static LRESULT WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch ( message )
    {
    case WM_DEVICECHANGE:
        OnDeviceChange( wParam, lParam ); // Set breakpoint (never gets here)
        break;

    default:
        break;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

PC进入 WndProc ,但不删除/插入我的USB设备。 PC从来没有进入 OnDeviceChange 。任何提示将不胜感激。我需要处理USB设备的意外插入/删除。如果它有所作为,则USB设备将显示为Windows的虚拟COM端口。感谢。

The PC gets into WndProc, but not when I remove/insert my USB device. The PC never seems to get into OnDeviceChange. Any tips would be appreciated. I need to handle unexpected insertions/removals of the USB device. If it makes a difference, the USB device appears as a virtual COM port to Windows. Thanks.

附加信息:使用类 CreateWindowEx 由 RegisterClassEx 返回的原子失败,并显示错误消息无法找到窗口类。

Aditional info: Calling CreateWindowEx using the class atom returned by RegisterClassEx fails with the error message, "Cannot find window class."

_hWnd = CreateWindowEx( 0, (LPCTSTR)&atom, pWindowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );

新方法

NEW APPROACH

我也在尝试这种新方法。我正在尝试写一个只有消息的窗口来接收USB设备的设备更改通知消息。我正在使用MFC,C ++和Visual Studio 2008.所有的编译,它运行没有崩溃或锁定,但事件处理程序从不被触发。感兴趣的设备作为虚拟COM端口安装在Windows上。

I'm also trying this new approach. I'm trying to get write a message-only window to receive device change notification messages for a USB device. I am using MFC, C++, and Visual Studio 2008. Everything compiles, and it runs without crashing or locking up, but the event handler is never triggered. The device of interest is installed on Windows as a virtual COM port.

我的主应用程序实例化了下面描述的类,然后等待使用一段时间的键盘轮询的字符输入循环。在这段等待时间内,我删除并插入我的USB设备,期望事件被触发。

My main application instantiates the class described below then waits for a character input from the keyboard polling using a while loop. It is during this wait time that I remove and insert my USB device expecting the event to get fired.

class CMessageOnlyWindow : public CWnd
{
    DECLARE_DYNAMIC(CMessageOnlyWindow)
private:
    DEV_BROADCAST_DEVICEINTERFACE * _pDevIF; // The notification filter.
    HDEVNOTIFY _hNotifyDev;             // The device notification handle.
public:
    CMessageOnlyWindow();
    virtual ~CMessageOnlyWindow();
protected:
    afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );
private:
    void RegisterNotification( void );
    void UnregisterNotification( void );
protected:
    DECLARE_MESSAGE_MAP()               // Must be last.
};

为了简单起见,我已经删除了所有的清理和错误处理:

For simplicity, I've removed all the cleanup and error-handling:

DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, \
    0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);

IMPLEMENT_DYNAMIC(CMessageOnlyWindow, CWnd)

CMessageOnlyWindow::CMessageOnlyWindow()
{
    CString cstrWndClassName = ::AfxRegisterWndClass( NULL );
    BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
        L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
    this->RegisterNotification();
}

CMessageOnlyWindow::~CMessageOnlyWindow() {}

BEGIN_MESSAGE_MAP(CMessageOnlyWindow, CWnd)
    ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()

afx_msg BOOL CMessageOnlyWindow::OnDeviceChange( UINT nEventType, DWORD dwData )
{
    switch ( nEventType ) // <-- Never gets here.
    {
    case DBT_DEVICEARRIVAL:
        break;

    case DBT_DEVICEREMOVECOMPLETE:
        break;

    default:
        break;
    }

    return TRUE;
}

void CMessageOnlyWindow::RegisterNotification(void)
{
    _pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    _pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    _pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    _pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
    _hNotifyDev = RegisterDeviceNotification( this->m_hWnd, _pDevIF, DEVICE_NOTIFY_WINDOW_HANDLE );
}

void CMessageOnlyWindow::UnregisterNotification(void)
{
    UnregisterDeviceNotification( _hNotifyDev );
}

任何想法或建议将不胜感激。如果缺少任何细节,请告诉我,我将很乐意添加它们。谢谢。

Any thoughts or suggestions would be much appreciated. If any details are missing, let me know, and I will be glad to add them. Thanks.

仅消息的窗口是否需要在新线程中启动,或者创建一个新窗口会自动分离一个新线程?

Does the message-only window need to be started in a new thread, or does creating a new window automatically spin off a new thread?

推荐答案

创建一个无效的虚拟窗口,但等待 WM_DEVICECHANGE 并使用 RegisterDeviceNotification 。 WMI在这里是一个过度的笨蛋,IMHO。

Create a dummy window that does nothing but wait for WM_DEVICECHANGE and register that window using RegisterDeviceNotification. WMI is an overkill here, IMHO.

这篇关于使用C ++检测Windows插入/删除事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆