C 获取可用驱动器及其大小的列表

C 获取可用驱动器及其大小的列表,c,windows,winapi,C,Windows,Winapi,我知道您可以使用getLogicalDrive()和GetDiskFreeSpaceEx()的组合来获取驱动器及其大小的列表。我一直在使用GetDiskFreeSpaceEx()没有问题,但是当我尝试使用GetLogicalDrives()时,我遇到了一个问题:我不想在将它传递给GetDiskFreeSpaceEx()之前检查每个可能的字母是否存在 有没有更简单的方法来获取系统上的驱动器(磁盘)列表及其大小?我在Windows上使用C 我想说清楚,我知道使用C#和WMI可能更容易,我对此不感兴趣

我知道您可以使用getLogicalDrive()和GetDiskFreeSpaceEx()的组合来获取驱动器及其大小的列表。我一直在使用GetDiskFreeSpaceEx()没有问题,但是当我尝试使用GetLogicalDrives()时,我遇到了一个问题:我不想在将它传递给GetDiskFreeSpaceEx()之前检查每个可能的字母是否存在

有没有更简单的方法来获取系统上的驱动器(磁盘)列表及其大小?我在Windows上使用C

我想说清楚,我知道使用C#和WMI可能更容易,我对此不感兴趣,所以请不要将其作为可能的解决方案发布。如果您想指出在C和WMI中是如何实现的,请点击这里。没有C++或C语言谢谢!(就像有人在中所做的)

您可以使用-这将返回一个包含系统上所有有效驱动器号的缓冲区

更新:

下面是我编写的示例程序,它使用GetLogicalDriveStrings枚举驱动器,并输出有关它们的一些基本信息

#include <windows.h>
#include <malloc.h>
#include <stdio.h>

int __cdecl main()
{
    DWORD cchBuffer;
    WCHAR* driveStrings;
    UINT driveType;
    PWSTR driveTypeString;
    ULARGE_INTEGER freeSpace;

    // Find out how big a buffer we need
    cchBuffer = GetLogicalDriveStrings(0, NULL);

    driveStrings = (WCHAR*)malloc((cchBuffer + 1) * sizeof(TCHAR));
    if (driveStrings == NULL)
    {
        return -1;
    }

    // Fetch all drive strings    
    GetLogicalDriveStrings(cchBuffer, driveStrings);

    // Loop until we find the final '\0'
    // driveStrings is a double null terminated list of null terminated strings)
    while (*driveStrings)
    {
        // Dump drive information
        driveType = GetDriveType(driveStrings);
        GetDiskFreeSpaceEx(driveStrings, &freeSpace, NULL, NULL);

        switch (driveType)
        {
        case DRIVE_FIXED:
            driveTypeString = L"Hard disk";
            break;

        case DRIVE_CDROM:
            driveTypeString = L"CD/DVD";
            break;

        case DRIVE_REMOVABLE:
            driveTypeString = L"Removable";
            break;

        case DRIVE_REMOTE:
            driveTypeString = L"Network";
            break;

        default:
            driveTypeString = L"Unknown";
            break;
        }

        printf("%S - %S - %I64u GB free\n", driveStrings, driveTypeString,
                  freeSpace.QuadPart / 1024 / 1024 / 1024);

        // Move to next drive string
        // +1 is to move past the null at the end of the string.
        driveStrings += lstrlen(driveStrings) + 1;
    }

    free(driveStrings);

    return 0;

}
GetLogicalDrives()是系统为此提供的API。简单的for()循环将其结果转换为驱动器号,如下所示:

DWORD d = GetLogicalDrives();
int i;
TCHAR Drive[] = _T("A:\\");
for(i=0;i<26;i++)
{
    if(d & (1<<i))
    {
        Drive[0] = _T('A')+i;
        GetDiskFreeSpaceEx(Drive, .....);
    }
}
DWORD d=GetLogicalDrives();
int i;
TCHAR驱动器[]=\u T(“A:\\”;

对于(i=0;i这是作为编辑的Michael代码。它在
free()
上区分故障,除非插入虚拟变量“singleDriveString”,因此:

#include <windows.h>
#include <malloc.h>
#include <stdio.h>

int __cdecl main()
{
DWORD cchBuffer;
WCHAR* driveStrings;
UINT driveType;
PWSTR driveTypeString;
ULARGE_INTEGER freeSpace;

// Find out how big a buffer we need
cchBuffer = GetLogicalDriveStrings(0, NULL);

driveStrings = (WCHAR*)malloc((cchBuffer + 1) * sizeof(TCHAR));
if (driveStrings == NULL)
{
    return -1;
}

// Fetch all drive strings    
GetLogicalDriveStrings(cchBuffer, driveStrings);

// Loop until we find the final '\0'
// driveStrings is a double null terminated list of null terminated strings)
wchar_t * singleDriveString = driveStrings;
while (*singleDriveString)
{
    // Dump drive information
    driveType = GetDriveType(singleDriveString);
    GetDiskFreeSpaceEx(singleDriveString, &freeSpace, NULL, NULL);

    switch (driveType)
    {
    case DRIVE_FIXED:
        driveTypeString = L"Hard disk";
        break;

    case DRIVE_CDROM:
        driveTypeString = L"CD/DVD";
        break;

    case DRIVE_REMOVABLE:
        driveTypeString = L"Removable";
        break;

    case DRIVE_REMOTE:
        driveTypeString = L"Network";
        break;

    default:
        driveTypeString = L"Unknown";
        break;
    }

    printf("%S - %S - %I64u GB free\n", singleDriveString, driveTypeString,
              freeSpace.QuadPart / 1024 / 1024 / 1024);

    // Move to next drive string
    // +1 is to move past the null at the end of the string.
    singleDriveString += lstrlen(singleDriveString) + 1;
}

free(driveStrings);

return 0;

} 
#包括
#包括
#包括
int_u_CDECLmain()
{
德沃德·奇布弗;
WCHAR*驱动字符串;
单元驱动型;
PWSTR驱动类型字符串;
ULARGE_整数自由空间;
//了解我们需要多大的缓冲区
cchBuffer=GetLogicalDriveStrings(0,NULL);
driveStrings=(WCHAR*)malloc((cchBuffer+1)*sizeof(TCHAR));
if(driveStrings==NULL)
{
返回-1;
}
//获取所有驱动器字符串
GetLogicalDriveStrings(cchBuffer、DriveString);
//循环,直到找到最终的“\0”
//DriveString是以null结尾的字符串的双null结尾列表)
wchar_t*singleDriveString=driveStrings;
while(*singleDriveString)
{
//转储驱动器信息
driveType=GetDriveType(singleDriveString);
GetDiskFreeSpaceEx(singleDriveString,&freeSpace,NULL,NULL);
开关(驱动型)
{
机箱驱动单元固定:
driveTypeString=L“硬盘”;
打破
机箱驱动器光盘:
driveTypeString=L“CD/DVD”;
打破
机箱驱动单元可拆卸:
driveTypeString=L“可移动”;
打破
机箱驱动单元远程:
driveTypeString=L“网络”;
打破
违约:
driveTypeString=L“未知”;
打破
}
printf(“%S-%S-%I64u GB自由\n”),singleDriveString,driveTypeString,
freeSpace.QuadPart/1024/1024/1024);
//移动到下一个驱动器串
//+1将移动超过字符串末尾的null。
singleDriveString+=lstrlen(singleDriveString)+1;
}
自由(驱动字符串);
返回0;
} 

+1,很好的q,+添加了winapi标签,希望能够正确地直接回答。“我不想检查每个可能的字母,看看它是否存在”。。。好的,您不想,但是您必须检查驱动器是否存在吗?如果是这样的话,请解释原因。因为在某些系统上,你可能会在远程驱动器上的环路上卡住。我想我会坚持下去,因为GetLogicalDriveStrings最终非常痛苦。顺便说一下,这是标记为
c
:)的第10000个问题,谢谢,但我无法让它工作。。。当我试图将每个字符串发送到GetDiskFreeSpaceEx时,它崩溃了。你有没有可能发布一段代码?看看劳里·斯特恩的答案,然后想想为什么
driveStrings
的增量会导致
free(driveStrings)
不再有效。这并不是我不满意。这是因为人们不注意问题和标签。这已经不是第一次了。如果我在C语言中特别问一些问题,为什么你会用VB回答?谢谢你的回答我想那是我<26=>也要注意“A:\\”中的缺失
#include <windows.h>
#include <malloc.h>
#include <stdio.h>

int __cdecl main()
{
DWORD cchBuffer;
WCHAR* driveStrings;
UINT driveType;
PWSTR driveTypeString;
ULARGE_INTEGER freeSpace;

// Find out how big a buffer we need
cchBuffer = GetLogicalDriveStrings(0, NULL);

driveStrings = (WCHAR*)malloc((cchBuffer + 1) * sizeof(TCHAR));
if (driveStrings == NULL)
{
    return -1;
}

// Fetch all drive strings    
GetLogicalDriveStrings(cchBuffer, driveStrings);

// Loop until we find the final '\0'
// driveStrings is a double null terminated list of null terminated strings)
wchar_t * singleDriveString = driveStrings;
while (*singleDriveString)
{
    // Dump drive information
    driveType = GetDriveType(singleDriveString);
    GetDiskFreeSpaceEx(singleDriveString, &freeSpace, NULL, NULL);

    switch (driveType)
    {
    case DRIVE_FIXED:
        driveTypeString = L"Hard disk";
        break;

    case DRIVE_CDROM:
        driveTypeString = L"CD/DVD";
        break;

    case DRIVE_REMOVABLE:
        driveTypeString = L"Removable";
        break;

    case DRIVE_REMOTE:
        driveTypeString = L"Network";
        break;

    default:
        driveTypeString = L"Unknown";
        break;
    }

    printf("%S - %S - %I64u GB free\n", singleDriveString, driveTypeString,
              freeSpace.QuadPart / 1024 / 1024 / 1024);

    // Move to next drive string
    // +1 is to move past the null at the end of the string.
    singleDriveString += lstrlen(singleDriveString) + 1;
}

free(driveStrings);

return 0;

}