监听windows消息获取U盘状态和u盘路径 实。现U盘文件状态监听

int main()

{

    WNDCLASS wc;
    ZeroMemory(&wc, sizeof(wc));
    wc.lpszClassName = TEXT("usbMsg");
    wc.lpfnWndProc = WndProc;

    RegisterClass(&wc);
    HWND h = CreateWindow(TEXT("usbMsg"), TEXT(""), 0, 0, 0, 0, 0,
        0, 0, GetModuleHandle(0), 0);

    MSG msg;
    while (true)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            WatchDirectory((LPTSTR)g_fileName);
        }
    }

}

//下面是回调函数监听U盘状态

LRESULT CALLBACK WndProc(HWND h, UINT msg, WPARAM wp, LPARAM lp)
{
    if (msg == WM_DEVICECHANGE)
    {
        if ((DWORD)wp == DBT_DEVICEARRIVAL) 
        {
            DEV_BROADCAST_VOLUME* p = (DEV_BROADCAST_VOLUME*)lp;
            if (p->dbcv_devicetype == DBT_DEVTYP_VOLUME) 
            {
                int l = (int)(log(double(p->dbcv_unitmask)) / log(double(2)));
                char panfu = 'A' + l;
                printf("%c come--\n", 'A' + l);
                g_hasIn = true;
                g_fileName[0] = panfu;
                g_fileName[1] = ':';
                g_fileName[2] = '\\';
                g_fileName[3] = '\\';
                g_fileName[4] = '\0';

            }
        }
        else if ((DWORD)wp == DBT_DEVICEREMOVECOMPLETE) 
        {
            DEV_BROADCAST_VOLUME* p = (DEV_BROADCAST_VOLUME*)lp;
            if (p->dbcv_devicetype == DBT_DEVTYP_VOLUME) 
            {
                int l = (int)(log(double(p->dbcv_unitmask)) / log(double(2)));
                printf("%c out--\n", 'A' + l);
                g_hasIn = false;
            }
        }
        return TRUE;
    }
    else return DefWindowProc(h, msg, wp, lp);
}

 

//监听u盘文件的变化,主要包括文件和目录的增删改

void WatchDirectory(LPTSTR lpDir)
{
    static DWORD dwWaitStatus;
    static HANDLE dwChangeHandles[2];
    static TCHAR lpDrive[4];//存储磁盘符
    static TCHAR lpFile[_MAX_FNAME];//用于存储文件名
    static TCHAR lpExt[_MAX_EXT];//用于存储对应文件的后缀
    static TCHAR lpDir2[_MAX_DIR];
    static bool bFirst = true;


   if (bFirst)
    {
        _tsplitpath_s(lpDir, lpDrive, 4, NULL, 0, lpFile, _MAX_FNAME, lpExt, _MAX_EXT);
        lpDrive[2] = (TCHAR)'\\';
        lpDrive[3] = (TCHAR)'\0';

        dwChangeHandles[0] = FindFirstChangeNotificationA(
            (LPCSTR)lpDir,
            TRUE,
            FILE_NOTIFY_CHANGE_FILE_NAME); //文件名   

        if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
            return;
        dwChangeHandles[1] = FindFirstChangeNotificationA(
            (LPCSTR)lpDir,
            TRUE,
            FILE_NOTIFY_CHANGE_DIR_NAME); //路径名  
        if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
            return;
        bFirst = false;
    }
    
    {
        dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, FALSE, 100);
        switch (dwWaitStatus)
        {
        case WAIT_OBJECT_0:
            if (FindNextChangeNotification(dwChangeHandles[0]) == FALSE)
                ExitProcess(GetLastError());
            break;
        case WAIT_OBJECT_0 + 1:
            if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE)
                ExitProcess(GetLastError());

            break;
        default:
            break;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以通过JDK中的Java Native Interface(JNI)调用操作系统的API来获取U盘的插拔事件,从而U盘监听。下面是一个简单的示例代码,演示了如何在Java中监听U盘的插拔事件: ```java import java.io.File; import java.util.Arrays; public class USBListener { static { System.loadLibrary("USBListener"); } public static native void start(); public static void main(String[] args) { USBListener.start(); } public static void onUSBInserted(String drivePath) { System.out.println("U盘已插入:" + drivePath); } public static void onUSBRemoved(String drivePath) { System.out.println("U盘已拔出:" + drivePath); } } ``` 上述代码中,我们定义了一个`USBListener`类,其中包含了一个`start()`方法,用于启动U盘监听功能。在`start()`方法中,我们通过JNI调用了一个名为`startUSBListener()`的C++函数,该函数启动了一个线程,循环遍历系统中的所有驱动器,并检查它们是否是可移动设备。如果是可移动设备,则将其保存到一个列表中,并且在后续的循环中持续检查它们是否被插拔。 当U盘被插入或拔出时,`startUSBListener()`函数会调用`onUSBInserted()`或`onUSBRemoved()`方法,这两个方法都是Java中的静态方法,可以在任何地方被调用。在本例中,我们只是简单地打印了一条消息,表示U盘已经插入或拔出了。 我们还需要在C++中`startUSBListener()`函数的代码,这里我们使用了Windows API来获取系统中的驱动器列表,并检查它们是否是可移动设备。以下是`startUSBListener()`函数的C++代码: ```cpp #include <Windows.h> #include <stdio.h> #include <stdlib.h> #include "USBListener.h" #define MAX_DRIVES 26 void startUSBListener(JNIEnv *env, jclass cls) { DWORD drives = GetLogicalDrives(); char driveLetter[] = "A:\\"; for (int i = 0; i < MAX_DRIVES; i++) { if ((drives & (1 << i)) != 0) { driveLetter[0] = 'A' + i; UINT type = GetDriveType(driveLetter); if (type == DRIVE_REMOVABLE) { HANDLE hDevice = CreateFile(driveLetter, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice != INVALID_HANDLE_VALUE) { char buf[MAX_PATH]; DWORD len; if (DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &buf, sizeof(buf), &len, NULL)) { STORAGE_DEVICE_NUMBER *number = (STORAGE_DEVICE_NUMBER *) &buf; char drivePath[MAX_PATH]; sprintf(drivePath, "\\\\.\\PhysicalDrive%d", number->DeviceNumber); HANDLE hDrive = CreateFile(drivePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDrive != INVALID_HANDLE_VALUE) { OVERLAPPED overlapped = {}; char buffer[512]; DWORD bytesReturned; if (DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &buf, sizeof(buf), &len, &overlapped)) { while (1) { Sleep(1000); if (DeviceIoControl(hDrive, IOCTL_STORAGE_CHECK_VERIFY2, NULL, 0, NULL, 0, &bytesReturned, &overlapped)) { USBListener::onUSBRemoved(driveLetter); break; } else { if (GetLastError() == ERROR_NOT_READY) { USBListener::onUSBInserted(driveLetter); break; } } } } CloseHandle(hDrive); } } CloseHandle(hDevice); } } } } } ``` 在上述代码中,我们首先调用`GetLogicalDrives()`函数获取系统中所有的驱动器列表,然后遍历这个列表,并检查每个驱动器是否是可移动设备。如果是可移动设备,则使用`CreateFile()`函数打开该设备,并获取其设备号。然后,我们将设备号作为参数,使用`CreateFile()`函数打开该设备对应的物理驱动器,并调用`DeviceIoControl()`函数发送`IOCTL_STORAGE_CHECK_VERIFY2`控制码,以检查该U盘是否已经被插入或拔出。 如果`DeviceIoControl()`函数返回了`ERROR_NOT_READY`错误码,则表示该U盘已经被拔出,我们就调用`USBListener::onUSBRemoved()`方法通知Java代码;如果`DeviceIoControl()`函数成功返回,则表示该U盘已经被插入,我们就调用`USBListener::onUSBInserted()`方法通知Java代码。在检测到U盘被插入或拔出后,我们需要使用`Sleep()`函数等待一段时间,以避免频繁地检查设备状态导致CPU占用过高。 最后,我们需要使用JNI将C++代码编译成动态链接库,以供Java代码调用。以下是`USBListener.h`文件的内容: ```cpp #include <jni.h> #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_USBListener_startUSBListener(JNIEnv *, jclass); #ifdef __cplusplus } #endif ``` 然后,我们需要使用C++编译器将上述代码编译成动态链接库,以供Java代码调用。在Windows下,可以使用MinGW或Visual C++等编译器来编译,例如: ```bash g++ -shared -o USBListener.dll -I"C:\Program Files\Java\jdk1.8.0_231\include" -I"C:\Program Files\Java\jdk1.8.0_231\include\win32" USBListener.cpp ``` 编译完成后,我们就可以在Java代码中使用`System.loadLibrary()`方法加载该动态链接库,并调用`USBListener.start()`方法启动U盘监听功能了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值