一、项目背景详细介绍

在 Windows 系统开发中,磁盘信息获取 是系统级编程的基础任务之一。
例如,系统监控工具、文件管理器、安装程序、资源统计工具等,往往需要知道:

  • 当前系统有几个磁盘分区;

  • 每个盘符的总容量;

  • 每个盘符的可用空间;

  • 磁盘的文件系统类型(如 NTFS、FAT32);

  • 是否为固定磁盘、移动设备或网络驱动器。

在 VC++ 中,Windows API 为我们提供了一整套获取磁盘信息的函数接口,如:

  • GetLogicalDriveStrings():获取系统所有驱动器字符串;

  • GetDriveType():判断驱动器类型;

  • GetDiskFreeSpaceEx():获取磁盘总空间与可用空间;

  • GetVolumeInformation():获取卷标及文件系统类型。

这些 API 让我们可以轻松地获取系统磁盘信息,而无需使用底层硬件接口。
掌握这些函数不仅能帮助你开发系统工具类应用,也能为注册系统、安装检测器、备份工具等提供底层支持。


二、项目需求详细介绍

本项目的目标是编写一个 控制台程序,在 Windows 环境下:

  1. 枚举出所有盘符;

  2. 获取每个盘符的:

    • 驱动器类型;

    • 总容量;

    • 可用容量;

    • 文件系统类型;

    • 卷标名称;

  3. 以人类可读格式输出,例如:


盘符:C:\ 类型:固定磁盘 卷标:System 文件系统:NTFS 总空间:476.9 GB 可用空间:312.5 GB -------------------------------

2.1 功能模块划分

模块 功能描述
盘符枚举模块 使用 GetLogicalDriveStrings() 获取所有盘符
盘符类型判断模块 使用 GetDriveType() 判断是否为固定磁盘或光驱
磁盘空间查询模块 使用 GetDiskFreeSpaceEx() 获取总空间与剩余空间
卷标与文件系统模块 使用 GetVolumeInformation() 读取卷标名与文件系统类型
输出模块 格式化打印结果

2.2 程序要求

  • 使用标准 VC++ Win32 控制台程序

  • 不依赖外部库;

  • 输出清晰对齐;

  • 所有 API 调用需有异常判断;

  • 注释详细,适合教学展示。


三、相关技术详细介绍

1. GetLogicalDriveStrings

函数原型:


DWORD GetLogicalDriveStrings( DWORD nBufferLength, LPTSTR lpBuffer );

作用:获取当前系统中所有逻辑驱动器的根目录字符串。
返回格式类似:"C:\\\0D:\\\0E:\\\0\0"
即每个盘符用 \0 分隔,最后以双 \0 结束。

2. GetDriveType


UINT GetDriveType(LPCTSTR lpRootPathName);

返回值定义如下:

返回值 含义
DRIVE_UNKNOWN 无法确定
DRIVE_NO_ROOT_DIR 无效路径
DRIVE_REMOVABLE 可移动磁盘(U盘)
DRIVE_FIXED 固定磁盘(硬盘分区)
DRIVE_REMOTE 网络磁盘
DRIVE_CDROM 光驱
DRIVE_RAMDISK RAM 磁盘

3. GetDiskFreeSpaceEx


BOOL GetDiskFreeSpaceEx(
  LPCTSTR lpDirectoryName,
  PULARGE_INTEGER lpFreeBytesAvailable,
  PULARGE_INTEGER lpTotalNumberOfBytes,
  PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

  • 获取磁盘的总字节数与可用字节数;

  • 以 64 位整数返回,支持大于 4GB 的磁盘;

  • 结果单位为字节(需手动转换为 GB)。

4. GetVolumeInformation


BOOL GetVolumeInformation(
  LPCTSTR lpRootPathName,
  LPTSTR lpVolumeNameBuffer,
  DWORD nVolumeNameSize,
  LPDWORD lpVolumeSerialNumber,
  LPDWORD lpMaximumComponentLength,
  LPDWORD lpFileSystemFlags,
  LPTSTR lpFileSystemNameBuffer,
  DWORD nFileSystemNameSize
);

可以获得:

  • 卷标名(Volume Label)

  • 文件系统(NTFS、FAT32)

  • 卷序列号等信息。


四、实现思路详细介绍

整个程序的逻辑非常清晰,可分为 5 步:

  1. 使用 GetLogicalDriveStrings() 获取所有盘符;

  2. 遍历每个盘符;

  3. 对每个盘符调用 GetDriveType() 判断类型;

  4. 使用 GetDiskFreeSpaceEx() 获取容量;

  5. 使用 GetVolumeInformation() 获取卷标与文件系统;

  6. 格式化输出所有信息。

程序总体流程图


[开始]
   ↓
[调用 GetLogicalDriveStrings 获取所有盘符]
   ↓
[循环遍历每个盘符]
   ↓
 ┌──────────────────────────┐
 │ 对每个盘符执行以下操作 │
 │   ↓                    │
 │  获取驱动器类型        │
 │  获取总空间与剩余空间  │
 │  获取卷标与文件系统名  │
 │  格式化输出结果        │
 └──────────────────────────┘
   ↓
[结束]


五、完整实现代码

// ====================================================
// 文件名:DiskInfo.cpp
// 功能:VC++ 获取电脑所有盘符及容量大小
// 作者:曹磊博客教学示例
// ====================================================

#include <windows.h>
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

// ------------------------------------
// 将字节数转换为 GB(保留 2 位小数)
// ------------------------------------
double BytesToGB(ULONGLONG bytes)
{
    return static_cast<double>(bytes) / (1024.0 * 1024.0 * 1024.0);
}

// ------------------------------------
// 获取驱动器类型字符串
// ------------------------------------
string GetDriveTypeString(UINT type)
{
    switch (type)
    {
    case DRIVE_UNKNOWN: return "未知类型";
    case DRIVE_NO_ROOT_DIR: return "无效路径";
    case DRIVE_REMOVABLE: return "可移动磁盘(U盘)";
    case DRIVE_FIXED: return "固定磁盘";
    case DRIVE_REMOTE: return "网络驱动器";
    case DRIVE_CDROM: return "光驱";
    case DRIVE_RAMDISK: return "虚拟内存盘";
    default: return "其他";
    }
}

// ------------------------------------
// 获取并打印单个驱动器信息
// ------------------------------------
void PrintDriveInfo(const string& drive)
{
    ULARGE_INTEGER freeBytesAvailable, totalBytes, freeBytes;
    char volumeName[MAX_PATH + 1] = { 0 };
    char fileSystemName[MAX_PATH + 1] = { 0 };

    UINT driveType = GetDriveTypeA(drive.c_str());

    // 获取磁盘空间信息
    if (!GetDiskFreeSpaceExA(drive.c_str(), &freeBytesAvailable, &totalBytes, &freeBytes))
    {
        cout << "无法访问驱动器:" << drive << endl;
        return;
    }

    // 获取卷标和文件系统信息
    GetVolumeInformationA(
        drive.c_str(),
        volumeName, sizeof(volumeName),
        NULL, NULL, NULL,
        fileSystemName, sizeof(fileSystemName)
    );

    cout << "盘符:" << drive << endl;
    cout << "类型:" << GetDriveTypeString(driveType) << endl;
    cout << "卷标:" << (strlen(volumeName) ? volumeName : "无") << endl;
    cout << "文件系统:" << (strlen(fileSystemName) ? fileSystemName : "未知") << endl;

    cout << fixed << setprecision(2);
    cout << "总空间:" << BytesToGB(totalBytes.QuadPart) << " GB" << endl;
    cout << "可用空间:" << BytesToGB(freeBytesAvailable.QuadPart) << " GB" << endl;
    cout << "-------------------------------------" << endl;
}

// ------------------------------------
// 主函数:获取所有盘符并打印信息
// ------------------------------------
int main()
{
    SetConsoleOutputCP(65001); // 设置控制台为 UTF-8 输出

    cout << "==============================" << endl;
    cout << " VC++ 获取电脑所有盘符信息演示" << endl;
    cout << "==============================" << endl;

    char buffer[256];
    DWORD length = GetLogicalDriveStringsA(sizeof(buffer), buffer);

    if (length == 0)
    {
        cout << "无法获取驱动器信息!" << endl;
        return 1;
    }

    char* p = buffer;
    while (*p)
    {
        string drive = p;
        PrintDriveInfo(drive);
        p += drive.length() + 1; // 下一个盘符
    }

    system("pause");
    return 0;
}

六、代码详细解读(仅解读方法作用)

  • BytesToGB:将字节转换为 GB 单位(方便人类阅读)。

  • GetDriveTypeString:将枚举类型(数值)转换为可读中文描述。

  • PrintDriveInfo

    • 调用 GetDriveTypeA() 获取盘符类型;

    • 调用 GetDiskFreeSpaceExA() 获取空间信息;

    • 调用 GetVolumeInformationA() 获取卷标与文件系统名称;

    • 输出格式化结果。

  • main()

    • 调用 GetLogicalDriveStringsA() 获取所有盘符;

    • 遍历每个盘符并调用 PrintDriveInfo 打印详细信息。


七、项目详细总结

本项目完整演示了如何使用 Windows API 获取电脑所有盘符及其详细信息。
程序运行后输出结果示例:

盘符:C:\
类型:固定磁盘
卷标:System
文件系统:NTFS
总空间:476.94 GB
可用空间:312.51 GB
-------------------------------------
盘符:D:\
类型:可移动磁盘(U盘)
卷标:MyUSB
文件系统:FAT32
总空间:15.62 GB
可用空间:10.31 GB
-------------------------------------

项目亮点

  • 纯 Windows API 实现;

  • 自动遍历所有盘符;

  • 输出详细系统信息;

  • 无需管理员权限;

  • 程序通用性强,可直接用于系统监控、资源管理等项目。


八、项目常见问题及解答

Q1:为什么部分盘符获取不到信息?
A:部分光驱或网络盘符在未加载介质时无法访问,GetDiskFreeSpaceEx 会返回失败。

Q2:为什么显示卷标为空?
A:该磁盘可能未设置卷标,或访问权限受限。

Q3:是否支持中文卷标?
A:支持。若需完整支持,请将项目字符集设置为 “使用多字节字符集” 或改用 GetVolumeInformationW()(宽字符版)。

Q4:容量显示错误?
A:请确保使用 GetDiskFreeSpaceEx 而非旧的 GetDiskFreeSpace,后者在超过 4GB 时会溢出。

Q5:如何只显示固定磁盘?
A:在遍历时只打印 GetDriveType(drive) == DRIVE_FIXED 的盘符即可。


九、扩展方向与性能优化

  1. 显示更多磁盘属性

    • 可调用 GetVolumeInformation 获取卷序列号;

    • 显示 文件系统标志(是否支持加密、压缩等)。

  2. 图形化界面(MFC)

    • 使用 MFC 创建磁盘信息窗口;

    • CListCtrl 中显示表格;

    • 实时刷新磁盘状态。

  3. 性能监控功能

    • 定时调用本程序模块;

    • 统计磁盘使用变化趋势;

    • 实现简易磁盘监控工具。

  4. 跨平台版本

    • 在 Linux 中可使用 statvfs 实现同功能;

    • 封装成统一接口,支持多平台。

  5. JSON 输出

    • 将结果转为 JSON 格式;

    • 便于前端界面或日志系统读取。

  6. 与注册程序结合

    • 结合磁盘序列号生成软件注册码;

    • 增强软件防盗版机制。


总结

通过本项目,你掌握了以下关键技能:

  • 使用 GetLogicalDriveStrings() 获取所有盘符;

  • 使用 GetDriveType() 判断磁盘类型;

  • 使用 GetDiskFreeSpaceEx() 获取容量;

  • 使用 GetVolumeInformation() 获取卷标与文件系统;

  • 将字节转化为 GB 并格式化输出。

该程序是所有 系统信息类软件 的基础模块,可直接集成到安装程序、监控工具或注册系统中。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐