我想使用 VC++ 在 Windows 中枚举所有可用的驱动器号(尚未使用)。
我怎样才能做到这一点?
::GetLogicalDrives()返回可用(读取:已使用)驱动器的列表作为掩码中的位。这应该包括映射的网络驱动器。因此,您可以简单地遍历这些位以找到为零的位,这意味着不存在驱动器。如果有疑问,您始终可以使用驱动器号 +调用::GetDriveType()":\"
(当然":\\"
,在 C 代码中,或者_T(":\\")
在 Unicode 感知术语中),并且应该返回DRIVE_UNKNOWN
或者DRIVE_NO_ROOT_DIR
如果驱动器可用。
GetLogicalDriveStrings
可以为您获取当前使用的驱动器号列表。
GetVolumeInformation
可用于获取有关特定驱动器的更多信息。
GetLogicalDriveStrings函数是一个很好的起点。
我不知道如何枚举它们,或者它是否会在 Visual c++ 上编译,但我在 Dev C++ 或代码块上对其进行了猛烈编码,以检查使用 CreateFile 可以访问哪些驱动器以及使用 GetDriveType 可以访问什么类型的驱动器。程序检查从 A 到 Z 的驱动器:
#include <windows.h>
#include <cstring>
#include <sstream>
#include <iostream>
using namespace std;
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, INT nShowCmd)
{
HANDLE hDevice = NULL;
HANDLE fileFind = NULL;
while(true)
{
Sleep(3005);
char drv='A';
while(drv!='[')
{
Sleep(105);
const char *charDrvCF;
const char *charDrv;
stringstream Str;
string drvStr;
Str<<drv;
Str>>drvStr;
string drvSpc=drvStr+":\\";
string fCheck="\\\\.\\";
string fhCheck=fCheck+drvStr+":";
charDrvCF=fhCheck.c_str();
charDrv=drvSpc.c_str();
hDevice=CreateFile(charDrvCF,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hDevice!=INVALID_HANDLE_VALUE)
{
switch(GetDriveType(charDrv))
{
case DRIVE_FIXED:
{
cout<<"Fixed drive detected: "<<charDrv<<endl;
break;
}
case DRIVE_REMOVABLE:
{
cout<<"Removable drive detected: "<<charDrv<<endl;
break;
}
case DRIVE_NO_ROOT_DIR:
{
cout<<"There is no volume mounted at the specified path. "<<charDrv<<endl;
break;
}
case DRIVE_REMOTE:
{
cout<<"The drive is a remote (network) drive. "<<charDrv<<endl;
break;
}
case DRIVE_CDROM:
{
cout<<"The drive is a CD-ROM drive. "<<charDrv<<endl;
break;
}
case DRIVE_RAMDISK:
{
cout<<"The drive is a RAM disk. "<<charDrv<<endl;
break;
}
case DRIVE_UNKNOWN:
{
cout<<"The drive type cannot be determined. "<<charDrv<<endl;
break;
}
}
}
drv++;
}
}
}
GetLogicalDrives 和 GetLogicalDriveStrings 看不到在不同命名空间中创建的网络驱动器。
例如,从本地系统下运行的服务调用函数将看不到登录用户创建的网络驱动器。
从 Windows XP 开始就会发生这种情况。以下文章描述了这种情况: http: //msdn.microsoft.com/en-us/library/windows/desktop/aa363908 (v=vs.85).aspx
std::vector<std::string> getListOfDrives() {
std::vector<std::string> arrayOfDrives;
char* szDrives = new char[MAX_PATH]();
if (GetLogicalDriveStringsA(MAX_PATH, szDrives));
for (int i = 0; i < 100; i += 4)
if (szDrives[i] != (char)0)
arrayOfDrives.push_back(std::string{szDrives[i],szDrives[i+1],szDrives[i+2]});
delete[] szDrives;
return arrayOfDrives;
}
返回驱动器向量,例如 C:\D:\E:\F:\
std::vector<std::string> drives = getListOfDrives();
for (std::string currentDrive : drives) {
std::cout << currentDrive << std::endl;
}
枚举它们
以下代码将完成这项工作:
for (w_chDrv = 'C'; w_chDrv <= 'Z'; w_chDrv++)
{
// make root path
_stprintf_s(w_szRootPath, 3, _T("%c:"), w_chDrv);
// get driver type
w_nDriverType = GetDriveType(w_szRootPath);
if ((w_nDriverType != DRIVE_REMOVABLE) && (w_nDriverType != DRIVE_FIXED))
continue;
// if you got here that means w_szRootPath is a valid drive
}