在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;
}