在编写某些Windows管理应用程序时,能够从自定义的驱动器选择列表框中进行选择无疑是非常专业的,使用Delphi或者C++的早期版本时我们都必须使用Win32所提供的许多关于获取磁盘信息的API函数来分别获取像卷标、序列号以及剩余空间等信息,现在我们将使用.Net框架和WMI(Windows Management Instrumentation - Windows 管理规范 )来实现上述功能。

一、 简介

若仅简单获取逻辑驱动器的名称列表我们使用.Net框架的Environment.GetLogicalDrives即可,但是若想获得更多关于磁盘驱动器的信息我们可以使用.Net框架下的System.Management 命名空间所提供的类和委托等对大量管理信息和管理事件的集合进行访问,这些信息和事件都与 WMI有关,该命名空间下的类实际上也是对WMI的一种封装,应用程序和服务可以使用从 ManagementObjectSearcher 和 ManagementQuery 派生的类,查询感兴趣的管理信息,例如在磁盘上还剩多少可用空间、当前 CPU 利用率是多少、某一应用程序正连接到哪一数据库等等,现在我们就以 C# 语言编写获取详细的逻辑驱动器信息的示例来展示.Net框架System.Management 命名空间的相关类和WMI编程,如下图:

二、技术要点

WMI最初是内置在 Windows 2000、Windows XP 和 Windows Server 2003 系列操作系统中核心的管理支持技术,目前WMI 已经是一种规范和基础结构,通过它可以访问、配置、管理和监视几乎所有的 Windows 资源例如磁盘、事件日志、文件、文件夹、文件系统、网络组件、操作系统设置、性能数据、打印机、进程、注册表设置、安全性、服务、共享、用户、组等等。在 WMI 之前,能够以编程方式访问 Windows 资源的惟一方法就是通过 Win32 API,现在我们除了使用WMI 脚本管理任何通过 WMI 公开的 Windows 资源外,还可以通过.Net框架对于WMI封装的System.Management 命名空间来轻松实现。

我们首先使用WMI查询来获取特定类名的SelectQuery实例,可以有两种方法创建该实例,一是可以传递一个已知的类名,譬如本文需要传递的类名为:Win32_LogicalDisk,代码如下:

SelectQuery selectQuery = new SelectQuery("win32_logicaldisk");

或者使用wql查询来创建查询类的实例,代码如下:

SelectQuery selectQuery = new SelectQuery("select * from win32_logicaldisk");

或者只获取类的部分属性,代码如下:

SelectQuery selectQuery = new SelectQuery("select Name,DriveType from win32_logicaldisk");

WQL查询语言是 SQL 的一个子集,查询通过包含以下内容限制返回的数据量1、SELECT 子句,指定只返回某些属性的数据;2、WHERE 子句,指定要返回的实例。Win32_LogicalDisk类在默认的本地MSDN里是无法找到的,只有在联机的MSDN里,Win32 and COM Development下的WMI下才能找到,同样可以使用的类还有很多很多,包含登录用户信息的Win32_Account类、包含本地和共享打印机信息的Win32_PrinterShare类等等。Win32_LogicalDisk里所包含的驱动器属性相当丰富,如下图:

然后使用该指定的SelectQuery查询创建ManagementObjectSearcher实例,此类是用于检索管理信息的较为常用的入口点之一,实例创建结束,我们需要调用Get方法执行查询以便检索管理对象的集合,当调用该方法时,ManagementObjectSearcher 在指定的范围内执行给定的查询,并返回与 ManagementObjectCollection 中的查询匹配的管理对象的集合,这是就可以在一个循环中遍历集合中的所有对象,并获取我们所感兴趣的对象的属性,代码如下:

……

SelectQuery selectQuery = new SelectQuery("select * from win32_logicaldisk");

ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery);

int i=0;

foreach (ManagementObject disk in searcher.Get()) {

//获取驱动器盘符

listView1.Items.Add(disk["Name"].ToString());

}

……

三、 程序实现

我们使用Visual Studio 2005来创建该示例程序,首先创建C#的Windows应用程序空白项目,为解决方案和项目取名为 GetLogicDrives,在默认的Form1窗体上我们各放置一个ListView和一个Button控件,保留控件的默认名称不变,将ListView1的View属性设为Details,双击ListView1的Columns属性,为详细信息视图添加5个列,分别为:盘符、卷标、类型、容量和可用空间,设置Button1的Text属性为Refresh,为该Button1添加单击事件,代码如下:

private void button1_Click(object sender, EventArgs e)

{

listView1.Items.Clear();

SelectQuery selectQuery = new SelectQuery("select * from win32_logicaldisk");

ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery);

int i=0;

foreach (ManagementObject disk in searcher.Get()) {

//盘符

listView1.Items.Add(disk["Name"].ToString());

//卷标

try

{

listView1.Items[i].SubItems.Add(disk["VolumeName"].ToString());

}

catch

{

listView1.Items[i].SubItems.Add("设备未准备好");

}

//驱动器类型

string DriveType;

try

{

DriveType = disk["DriveType"].ToString();

switch (DriveType)

{

case "0":

listView1.Items[i].SubItems.Add("未知设备");

break;

case "1":

listView1.Items[i].SubItems.Add("未分区");

break;

case "2":

listView1.Items[i].SubItems.Add("可移动磁盘");

break;

case "3":

listView1.Items[i].SubItems.Add("硬盘");

break;

case "4":

listView1.Items[i].SubItems.Add("网络驱动器");

break;

case "5":

listView1.Items[i].SubItems.Add("光驱");

break;

case "6":

listView1.Items[i].SubItems.Add("内存磁盘");

break;

}

}

catch

{

listView1.Items[i].SubItems.Add("未知类型");

}

//容量

try

{

listView1.Items[i].SubItems.Add(GetSizeUseUnit(disk["Size"].ToString()));

}

catch

{

listView1.Items[i].SubItems.Add("设备未准备好");

}

//剩余空间

try

{

listView1.Items[i].SubItems.Add(GetSizeUseUnit(disk["FreeSpace"].ToString()));

}

catch

{

listView1.Items[i].SubItems.Add("设备未准备好");

}

i++;

}

}

我们使用了格式化显示磁盘空间容量的自定义函数GetSizeUseUnit,当不使用该函数时磁盘容量和可用空间的显示如下:

private string GetSizeUseUnit(string size)

{

double dSpace = Convert.ToDouble(size);

string sSpace = dSpace.ToString("N");

string[] tmp;

string rtnSize = "0";

tmp = sSpace.Split(',');

switch (tmp.GetUpperBound(0))

{

case 0:

rtnSize = tmp[0] + " 字节";

break;

case 1:

rtnSize = tmp[0] + "." + tmp[1].Substring(0,2) + " K";

break;

case 2:

rtnSize = tmp[0] + "." + tmp[1].Substring(0, 2) + " M";

break;

case 3:

rtnSize = tmp[0] + "." + tmp[1].Substring(0, 2) + " G";

break;

case 4:

rtnSize = tmp[0] + "." + tmp[1].Substring(0, 2) + " T";

break;

}

return rtnSize;

}

使用了上述自定义格式化显示的函数后,磁盘容量和可用空间的显示就显得非常简洁和直观。

最后,为了确保在窗体启动时自动获取驱动器信息,需要在窗体的Load事件中模拟对Button1的单击操作,代码如下:

private void Form1_Load(object sender, EventArgs e)

{

button1_Click(sender, e);

}

四、 总结

我们利用.Net框架System.Management 命名空间所提供的WMI封装非常简单的实现了获取逻辑驱动器的详细信息,除了上述信息我们还可以轻松的获取Windows资源大部分信息,比起使用Win32API要更加简单和有效。该示例程序在Windows XP SP2 + Visual Studio 2005 下编译和调试通过。

c# 获取路径的盘符_c#获取驱动器盘符相关推荐

  1. springMVC参数的传递方式(1.通过@PathVariabl获取路径参数,2.@ModelAttribute获取数据,3.HttpServletRequest取参,4@RequestParam)

     通过@PathVariabl注解获取路径中传递参数 JAVA 1     @RequestMapping(value = "/{id}/{str}") 2     publi ...

  2. python获取路径下所有文件_Python获取路径下所有文件名

    交易系统使用storm,在消息高可靠情况下,如何避免消息重复 概要:在使用storm分布式计算框架进行数据处理时,如何保证进入storm的消息的一定会被处理,且不会被重复处理.这个时候仅仅开启stor ...

  3. java 获取记事本的行数_C++ 获取文本文件的行数

    Java一次读取文本文件所有内容 标签: java encoding string file byte null 2011-08-18 11:24 6793人阅读 评论(0) 收藏 举报 本文章已收录 ...

  4. Java项目中读取properties文件,以及六种获取路径的方法

    下面1-4的内容是网上收集的相关知识,总结来说,就是如下几个知识点: 最常用读取properties文件的方法 InputStream in = getClass().getResourceAsStr ...

  5. java获取iOS可写目录_ios 获取文件目录路径方法大全

    我们的app在手机中存放的路径是:/var/mobile/Applications/4434-4453A-B453-4ADF535345ADAF344 后面的目录4434-4453A-B453-4AD ...

  6. python 获取路径的盘符_python获取磁盘号下盘符步骤详解

    这次主要教的是如何通过Python 获取Windows系统下的所有的磁盘盘符,以列表的形式展示出来,获取磁盘号下的盘符包括能够获取到我们正在插在电脑上的U盘,也可以读取到,希望能够对你们在学习过程中有 ...

  7. 批处理获取U盘、可移动硬盘的盘符

    作者:朱金灿 来源:http://blog.csdn.net/clever101 关于批处理获取U盘.可移动硬盘的盘符,网上有三种做法: [方案一]fsutil @echo offfor %%a in ...

  8. linux java 获取路径怎么写_linux中java获取路径的实例代码

    linux中java获取路径怎么写? 在Unix/Linux中,路径的分隔采用正斜"/",比如"cd /home/java". 在java的代码开发中 \ 是代 ...

  9. linux java 获取路径怎么写_linux中java获取路径怎么写?

    linux中java获取路径怎么写? 在Unix/Linux中,路径的分隔采用正斜"/",比如"cd /home/java". 在java的代码开发中 是代表转 ...

最新文章

  1. 入门深度学习的必备数学知识
  2. Docker虚拟化容器的使用
  3. lda 吗 样本中心化 需要_PCA 与 LDA 分析
  4. java学习笔记(十)----String类和StringBuffer类
  5. P11 非线性系统-《Matlab/Simulink与控制系统仿真》程序指令总结
  6. android webview 多文件上传,Android中的webview支持页面中的文件上传实例代码
  7. mysql select from user_mysql查询[select * from user limit 0, 10;]
  8. 关于 SAP Spartacus SSR 模式和 CSR 模式下重复发送 HTTP 请求调用 OCC API 的问题
  9. ai 图灵测试_适用于现代AI系统的“视觉图灵测试”
  10. dataframe数据按行做线性拟合
  11. lisp封装成vla函数_牛逼,自动将函数或者命令行工具转换成 Web 服务
  12. 【Win7系统 沙滩啤酒桌面主题】
  13. 如何快速入门学习UG编程
  14. 微信公众号排版 | 汇总和实战
  15. Computer Science Theory for the Information Age-2: 高维空间中的正方体和Chernoff Bounds
  16. 水果店圈子:水果店开业宣传文字怎么发,水果店准备开业怎么发朋友圈
  17. 有关计算机时代的英语阅读理解题,2020-2021高考英语阅读理解综合经典题附详细答案...
  18. 住在储藏室的小夫妻【zt】
  19. wcf第3步之报文分析及原生调用
  20. 【翻译】Dagre-D3 文档整理和翻译

热门文章

  1. (三)PYTHON字典 元祖 列表尝试应用
  2. Go语言入门——Go语言环境搭建
  3. linux-ntpdate同步更新时间
  4. 动态规划算法的应用模型
  5. Ubuntu 中Mysql 操作
  6. (转)Web Services使用多态(XmlInclude) ,支持自定义类型
  7. 浅谈项目开发现状(一)
  8. oracle10g 监听服务无法启动
  9. 牛客网--牛牛找工作
  10. openlayers实例_介绍OpenLayers