期末考试终于全部考完了,终于开始写代码了。
这几天先解决一下这个历史遗留问题。问题是这样的:PC 端自动获取USB设备盘符并且读取特定文件夹下面的文件。
首先找到下面这些资料来参考:
如何获得U盘盘符:
http://topic.csdn.net/u/20081118/14/dc0ab5bd-3a1d-4868-bb1e-4ff638fc82c2.html
http://hi.baidu.com/harry945/blog/item/7905377f5b40490229388a2a.html
http://www.doc88.com/p-941579862185.html
http://msdn.microsoft.com/en-us/library/aa363480%28VS.85%29.aspx
方法有很多。这里介绍一下一个比较简单的方法:
首先是捕捉WM_DEVICECHANGE消息:
DBT_DEVICEARRIVAL表示有新的移动设备进入。
找到了下面这段c++代码如下:
//以找usb设备为例,取得的usb盘符放在UsbRoot里面,len为UsbRoot字符数组的长度
BOOL GetUsbRoot(CHAR* UsbRoot,SHORT len)
{
DWORD dwDriveStrLen = 0;
CHAR *pDriveName = NULL;
UINT Drive = 0;
if (UsbRoot == NULL || len <= 0)
{
return FALSE;
}
dwDriveStrLen = ::GetLogicalDriveStrings(0,NULL);//取得你计算机上盘符数目
if (0 == dwDriveStrLen)
{
return FALSE;
}
CHAR *szDriveNameBuff = (CHAR*)malloc(dwDriveStrLen);//根据你机器上的磁盘数目分配内存
if (NULL == szDriveNameBuff)
{
return FALSE;
}
memset(szDriveNameBuff,0,sizeof(szDriveNameBuff));
::GetLogicalDriveStrings(dwDriveStrLen,szDriveNameBuff);//取得你计算机上所有盘符
pDriveName = szDriveNameBuff;
while (*pDriveName != NULL)//遍历所有盘符,找到你需要的设备
{
Drive = ::GetDriveType(pDriveName);
switch (Drive)
{
case DRIVE_UNKNOWN://未知设备
break;
case DRIVE_NO_ROOT_DIR:
break;
case DRIVE_REMOVABLE://usb设备
//如果为usb,在这里进行相关处理
//break;
case DRIVE_FIXED://硬盘
break;
case DRIVE_REMOTE://网络硬盘,如:局域网服务器上的盘
break;
case DRIVE_CDROM://光驱
break;
case DRIVE_RAMDISK://RAM 盘
break;
default:
break;
}
pDriveName += strlen(pDriveName) + 1;
}
if (szDriveNameBuff != NULL)
{
free(szDriveNameBuff);
szDriveNameBuff = NULL;
}
return FALSE;
}
(一)
首先是捕捉WM_DEVICECHANGE消息:
DBT_DEVICEARRIVAL表示有新的移动设备进入。
(二)
GetLogicalDriveStrings 获得所有盘符,然后挨个判断是不是可移动设备。
(三)
复制USB文件到自己电脑上。
(四)
设置窗口隐藏。在D盘创建一个文件夹CopyFromUSB。当文件复制完成以后自动关闭程序
/*------------------------------------------------------------
自动读取USB设备指定文件
作者:Miibotree
------------------------------------------------------------*/
#include <windows.h>
#include <Dbt.h>
#include <WinBase.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int SearchDrive();
int ReadUSBFile(LPCWSTR lpFileName);
int SearchAllFile(LPWSTR lpSource, LPWSTR lpDest);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow (hwnd, SW_HIDE) ;
//ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rect;
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
return 0 ;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DEVICECHANGE:
switch (wParam)
{
case DBT_DEVICEARRIVAL: //设备插进来
//case DBT_DEVTYP_DEVINST:
SearchDrive();
PostQuitMessage (0) ;
return 0;
}
return 0;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
int SearchDrive()
{
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
UINT DriveNumber= NULL;
TCHAR DriveBuffer[100];
TCHAR *pDriveName = NULL;
DWORD DriveLength = sizeof(DriveBuffer);
int iResult = GetLogicalDriveStrings(DriveLength, (LPTSTR)DriveBuffer);
if (iResult == 0)
{
MessageBox(NULL, TEXT("获取盘符出错"), TEXT("出错了"), MB_OK);
return 0;
}
pDriveName = DriveBuffer;
while (*pDriveName != NULL)
{
DriveNumber = GetDriveType((LPCTSTR)pDriveName);
if (DriveNumber == DRIVE_REMOVABLE)
{
ReadUSBFile(pDriveName);
}
pDriveName += wcslen(pDriveName) + 1;
}
return 0;
}
int ReadUSBFile(LPCWSTR lpFileName)
{
TCHAR lpDest[MAX_PATH] = L"d:\\CopyFromUSB\\";
CreateDirectory(lpDest, NULL);
SearchAllFile((LPWSTR)lpFileName, lpDest);
return 0;
}
int SearchAllFile(LPWSTR lpSource, LPWSTR lpDest)
{
WIN32_FIND_DATA FindFileData;
HANDLE hListFile;
TCHAR szFilePath[MAX_PATH] = L"\0";
TCHAR szFileFull[MAX_PATH] = L"\0";
DWORD i = 0;
wcscat(szFilePath, lpSource);
wcscat(szFilePath,L"\\*.*");
hListFile = FindFirstFile(szFilePath,&FindFileData);
if (hListFile == INVALID_HANDLE_VALUE)
{
return 1;
}
else
{
do
{
memset(szFileFull, 0, sizeof(szFileFull));
//判断隐藏的本目录. 及上级目录..
if (wcscmp(FindFileData.cFileName,TEXT(".")) == 0 || wcscmp(FindFileData.cFileName,TEXT("..")) == 0)
{
continue;
}
wsprintf(szFileFull, L"%s\\%s", lpSource, FindFileData.cFileName);
TCHAR lpDestDir[MAX_PATH];
wsprintf(lpDestDir, L"%s\\%s", lpDest, FindFileData.cFileName);
CopyFile(szFileFull, lpDestDir, NULL);
//判断是否是文件夹
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
CreateDirectoryW(lpDestDir, NULL);
SearchAllFile(szFileFull, lpDestDir);
}
} while(FindNextFile(hListFile,&FindFileData));
}
return 0;
}