在C+中检测USB插入/删除+;非GUI应用程序 我想通过一个C++应用程序来检测一个特定的(自定义)USB设备的插入/删除,它在后台运行,没有GUI。

在C+中检测USB插入/删除+;非GUI应用程序 我想通过一个C++应用程序来检测一个特定的(自定义)USB设备的插入/删除,它在后台运行,没有GUI。,c++,windows,usb,C++,Windows,Usb,我已经看到了很多问题及其解决方案registerdevisionification还有示例代码 但这些应用程序都有一些窗口/窗体/GUI。我的应用程序没有任何。 我如何在我的应用程序中使用它 我的最后一个选择是创建一个不可见的窗口。。。但是还有其他的出路吗???创建一个。尽管名称不同,它实际上只是一个消息队列 首先创建一个服务,然后在RegisterDeviceNotification中,给出该服务的句柄,而不是窗口句柄 也相应地调整寄存器设备化的第三个参数。\define ANSI #defi

我已经看到了很多问题及其解决方案
registerdevisionification
还有示例代码

但这些应用程序都有一些窗口/窗体/GUI。我的应用程序没有任何。 我如何在我的应用程序中使用它


我的最后一个选择是创建一个不可见的窗口。。。但是还有其他的出路吗???

创建一个。尽管名称不同,它实际上只是一个消息队列

首先创建一个服务,然后在
RegisterDeviceNotification
中,给出该服务的句柄,而不是窗口句柄

也相应地调整
寄存器设备化的第三个参数。

\define ANSI
#define ANSI
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT   0x0501

#include <windows.h>
#include <winuser.h>
#include <Dbt.h>

#include <string>
#include <iostream>
#include <stdexcept>

#define HID_CLASSGUID {0x4d1e55b2, 0xf16f, 0x11cf,{ 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}}
#define CLS_NAME "DUMMY_CLASS"
#define HWND_MESSAGE     ((HWND)-3)

LRESULT message_handler(HWND__* hwnd, UINT uint, WPARAM wparam, LPARAM lparam)
{
    switch (uint)
    {
    case WM_NCCREATE: // before window creation
        return true;
        break;

    case WM_CREATE: // the actual creation of the window
    {
        // you can get your creation params here..like GUID..
        LPCREATESTRUCT params = (LPCREATESTRUCT) lparam;
        GUID InterfaceClassGuid = *((GUID*)params->lpCreateParams);
        DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
        ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
        NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
        NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
        NotificationFilter.dbcc_classguid = InterfaceClassGuid;
        HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &NotificationFilter,
                                                           DEVICE_NOTIFY_WINDOW_HANDLE);
        if(dev_notify == NULL)
        {
            throw std::runtime_error("Could not register for devicenotifications!");
        }
        break;
    }

    case WM_DEVICECHANGE:
    {
        PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lparam;
        PDEV_BROADCAST_DEVICEINTERFACE lpdbv = (PDEV_BROADCAST_DEVICEINTERFACE) lpdb;
        std::string path;
        if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
        {
            path = std::string(lpdbv->dbcc_name);
            switch (wparam)
            {
            case DBT_DEVICEARRIVAL:
                std::cout << "new device connected: " << path << "\n";
                break;

            case DBT_DEVICEREMOVECOMPLETE:
                std::cout << "device disconnected: " << path << "\n";
                break;
            }
        }
        break;
    }

    }
    return 0L;
}

int main(int argc, char* argv[])
{
    HWND hWnd = NULL;
    WNDCLASSEX wx;
    ZeroMemory(&wx, sizeof(wx));

    wx.cbSize = sizeof(WNDCLASSEX);
    wx.lpfnWndProc = reinterpret_cast<WNDPROC>(message_handler);
    wx.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0));
    wx.style = CS_HREDRAW | CS_VREDRAW;
    wx.hInstance = GetModuleHandle(0);
    wx.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wx.lpszClassName = CLS_NAME;

    GUID guid = HID_CLASSGUID;

    if (RegisterClassEx(&wx))
    {
        hWnd = CreateWindow(CLS_NAME, "DevNotifWnd", WS_ICONIC,
                            0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE,
                            NULL, GetModuleHandle(0), (void*)&guid);
    }

    if(hWnd == NULL)
    {
        throw std::runtime_error("Could not create message window!");
    }

    std::cout << "waiting for new devices..\n";

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
#定义WIN32_精益_和_平均值 #定义_WIN32_WINNT 0x0501 #包括 #包括 #包括 #包括 #包括 #包括 #定义HID_类GUID{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30} #定义CLS_名称“虚拟_类” #定义HWND_消息((HWND)-3) LRESULT消息\u处理程序(HWND\uuu*HWND、UINT-UINT、WPARAM-WPARAM、LPARAM-LPARAM) { 开关(uint) { 案例WM\u NCCREATE://在创建窗口之前 返回true; 打破 case WM_CREATE://窗口的实际创建 { //您可以在此处获取创建参数..如GUID。。 LPCREATESTRUCT参数=(LPCREATESTRUCT)LPRAM; GUID InterfaceClassGuid=*((GUID*)参数->lpCreateParams); 开发广播设备接口通知过滤器; 零内存(&NotificationFilter,sizeof(NotificationFilter)); NotificationFilter.dbcc_size=sizeof(设备接口); NotificationFilter.dbcc_devicetype=DBT_DEVTYP_DEVICEINTERFACE; NotificationFilter.dbcc_classguid=InterfaceClassGuid; HDEVNOTIFY dev_notify=RegisterDeviceNotify(hwnd)和NotificationFilter, 设备(通知、窗口、手柄); if(dev_notify==NULL) { 抛出std::runtime_错误(“无法注册devicenotifications!”); } 打破 } 案例WM_设备变更: { PDEV_广播_HDR lpdb=(PDEV_广播_HDR)LPRAM; PDEV_广播_设备接口lpdbv=(PDEV_广播_设备接口)lpdb; std::字符串路径; if(lpdb->dbch\u设备类型==DBT\u DEVTYP\u设备接口) { path=std::string(lpdbv->dbcc_名称); 交换机(wparam) { 案例DBT_设备到达: std::cout外部USB存储设备检测器
此程序(C++)检测笔驱动器存储卡外部硬盘驱动器(每当插入新的USB存储设备时)-

#包括
#包括
#包括
#包括
使用名称空间std;
串驱动器;
char getRemovableDisk();
内部主(空){
char driveLetter=getRemovableDisk();
而(1){
driveLetter=getRemovableDisk();
if(driveLetter!=“0”){
printf(“%c\n”,driveLetter);
}
睡眠(1000);
}
返回0;
}
char getRemovableDisk(){
char-drive='0';
char szLogicalDrives[MAX_PATH];
DWORD dwResult=GetLogicalDriveStrings(最大路径,szLogicalDrives);
字符串currentDrive=“”;

/couth此C++代码检测USB存储设备的插入和删除。 这也会同时检测USB设备的多次插入和移除。

c++代码:在VISUAL STUDIO 2015中测试

您还可以检查其他类型的设备以进行删除和插入。 只需将传递的字符数组填充到函数getUSBStorageDeviceList()中代码的
if-else
中的其他类型的设备即可

#包括“stdafx.h”
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
#定义最大字母26
字符上一个驱动器列表[最大字母];
char NEW_DRIVE_LIST[最大字母];
/*获取字符数组中的驱动器列表*/
void getUSBStorageDeviceList(字符驱动器[]){
整数计数=0;
char szLogicalDrives[MAX_PATH];
大小=strlen(szLogicalDrives)+1;
wchar_t*text=新的wchar_t[size];
尺寸不要太大;
mbstowcs_s(超大、文本、大小、szLogicalDrives、大小-1);
DWORD dwResult=GetLogicalDriveStrings(最大路径,text);//text=szLogicalDrives
WCHAR*szSingleDrive=text;
while(*szSingleDrive)
{
UINT nDriveType=GetDriveType(szSingleDrive);
//printf(“\nFUNC:getRemovableDisk,驱动器名%d=%s”,++计数,szSingleDrive);
如果(nDriveType==驱动器未知){

//难道你不想让你的代码可以在不同的操作系统之间移植吗?只有Windows…但是,是的,Windows XP到Windows 7(或者也可能是Win 8!)创建不可见的窗口,并在其窗口过程中处理通知消息。你需要在包含消息循环的单独线程中进行此操作。查看此处,它的状态为:“…发送到Windows的消息…”听起来您实际上想要的是“服务”,而不是应用程序,在这种情况下,您可以传递“服务状态句柄”而不是“HWND”到
RegisterDeviceNotification
@DavidHeffernan:取决于
dbch_设备类型
,但您需要
RegisterDeviceNotification
的消息不会广播(毕竟这是函数的全部要点)@DavidHeffernan:不是广播的,不是。但是对于一个定制设备,我并不期望广播消息。它们使用pub/sub而不是广播。好吧,我对自己再也不确定了。使用一个普通的窗口似乎可以解决这个问题()但我不知道为什么。我想我会在这里删除我的评论,因为我的立场不稳。只有消息的窗口不会接收
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <string>

using namespace std;

string allDrives;

char getRemovableDisk();

int main(void){

    char driveLetter = getRemovableDisk();
    while(1){
        driveLetter = getRemovableDisk();
        if(driveLetter!='0'){
            printf("%c \n", driveLetter);
        }

        Sleep(1000);
    }

    return 0;
}

char getRemovableDisk(){
    char drive='0';

    char szLogicalDrives[MAX_PATH];
    DWORD dwResult = GetLogicalDriveStrings(MAX_PATH, szLogicalDrives);

    string currentDrives="";

    //cout << dwResult << endl;
    for(int i=0; i<dwResult; i++)
    {
        if(szLogicalDrives[i]>64 && szLogicalDrives[i]< 90)
        {
            currentDrives.append(1, szLogicalDrives[i]);

            if(allDrives.find(szLogicalDrives[i]) > 100)
            {
                drive = szLogicalDrives[i];
            }
        }
    }

    allDrives = currentDrives;

    return drive;
}
    #include "stdafx.h"
    #include <stdio.h>
    #include <time.h>
    #include <windows.h>
    #include <string>
    #include<iostream>

    using namespace std;

    #define MAX_LETTER 26
    char PREV_DRIVE_LIST[MAX_LETTER];
    char NEW_DRIVE_LIST[MAX_LETTER];

    /* To GET DRIVE LIST in char ARRAY */
    void getUSBStorageDeviceList(char drive[]) {

        int count = 0;

        char szLogicalDrives[MAX_PATH];
        size_t size = strlen(szLogicalDrives) + 1;
        wchar_t* text = new wchar_t[size];

        size_t outSize;
        mbstowcs_s(&outSize, text, size, szLogicalDrives, size - 1);

        DWORD dwResult = GetLogicalDriveStrings(MAX_PATH, text); // text = szLogicalDrives
        WCHAR* szSingleDrive = text;

        while (*szSingleDrive)
        {
            UINT nDriveType = GetDriveType(szSingleDrive);

        //  printf("\nFUNC: getRemovableDisk, Drive Name%d= %s", ++count, szSingleDrive);

            if (nDriveType == DRIVE_UNKNOWN) {
            //  cout << "\nDrive type : Unknown: The drive type cannot be determined." << endl;
            }
            else if (nDriveType == DRIVE_NO_ROOT_DIR) {
            //  cout << "\nDrive type : Invalid Root Directory Media: The root path is invalid." << endl;
            }
            else if (nDriveType == DRIVE_REMOVABLE) {
            //  cout << "\nDrive type :  Removable Media:" << endl;
                char letter = szSingleDrive[0];
                drive[letter - 65] = letter;
            }
            else if (nDriveType == DRIVE_FIXED) {
                //cout << "\nDrive type : Fixed Media: " << endl;
            }
            else if (nDriveType == DRIVE_REMOTE) {
                //cout << "\nDrive type : Remote Media: The drive is a remote (network) drive.." << endl;
            }
            else if (nDriveType == DRIVE_CDROM) {
                //cout << "\nDrive type : CD ROM:   The drive is a CD-ROM drive." << endl;
            }
            else if (nDriveType == DRIVE_RAMDISK) {
                //cout << "\nDrive type : RAM Disk: The drive is a RAM disk." << endl;
            }

            szSingleDrive += wcslen(szSingleDrive) + 1; // next drive 
        }
    }

    int main(void) {

        int count = 0;
        for (int i = 0; i < MAX_LETTER; i++) {
            PREV_DRIVE_LIST[i] = '0';
            NEW_DRIVE_LIST[i] = '0';
        }
        // initial drive list which is already attached 
        getUSBStorageDeviceList(PREV_DRIVE_LIST);

        while (1) {

            getUSBStorageDeviceList(NEW_DRIVE_LIST);
            count = 1;

            /* Check for insertion and removabal*/

            for (int i = 0; i < MAX_LETTER; i++) {
                // check for new drive
                if ((NEW_DRIVE_LIST[i] >= 65 && NEW_DRIVE_LIST[i] <= 89) && (PREV_DRIVE_LIST[i] == '0')) {

                    printf("\nNew Device Inserted%d : %c", count++, NEW_DRIVE_LIST[i]);
                    PREV_DRIVE_LIST[i] = NEW_DRIVE_LIST[i];
                }
            }
                // fill ALl zero 
                for (int i = 0; i < MAX_LETTER; i++) {
                    NEW_DRIVE_LIST[i] = '0';
                }
                // update NEW drive list
                getUSBStorageDeviceList(NEW_DRIVE_LIST);

                for (int i = 0; i < MAX_LETTER; i++) {
                    // check for removed drive
                    if ((PREV_DRIVE_LIST[i] >= 65 && PREV_DRIVE_LIST[i] <= 89) && (NEW_DRIVE_LIST[i] == '0')) {
                        printf("\nDevice Removed%d : %c", count++, PREV_DRIVE_LIST[i]);
                        PREV_DRIVE_LIST[i] = NEW_DRIVE_LIST[i];
                    }
            }
                Sleep(500);
        }

        return 0;
    }