我想通过在后台运行并且没有GUI的C ++应用程序来检测特定(自定义)USB设备的插入/删除。
我看到很多问题及其解决方案RegisterDeviceNotification
也在MSDN
但是这些应用程序都有一些Window / Form / GUI。我的申请没有。 如何在我的应用程序中使用它?
我的最后一个选择是创建一个不可见的窗口......但还有其他出路吗?
答案 0 :(得分:5)
创建message-only window。尽管名称,它实际上只是一个消息队列。
答案 1 :(得分:3)
#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;
}
这个简单的程序创建了一个不可见的窗口,它的消息处理程序也接收'RegisterDeviceNotification'的通知。
答案 2 :(得分:2)
此程序(C ++)检测笔式驱动器,存储卡&amp; 外置硬盘(每当插入新的 USB存储设备时) -
#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;
}
备注:此代码段只能检测一个新设备(即使一次插入多个设备)。但是,当然,您也可以通过稍微改变来实现多重检测。 :)
答案 3 :(得分:0)
首先创建服务,然后在RegisterDeviceNotification
中,提供该服务的句柄而不是窗口句柄。
同时相应地调整RegisterDeviceNotification
的第三个参数。
答案 4 :(得分:0)
此c ++代码检测两个USB存储设备的插入和删除。
这还将检测同时插入和移除USB设备。
c ++代码:已在VISUAL STUDIO 2015中进行了测试
您还可以检查是否有其他类型的设备可以卸下和插入。 只需将传递的char数组填充到函数 getUSBStorageDeviceList()
中的代码的if else
中的其他类型的设备上
#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;
}