事情的起因是一开始我们有个功能是获取Windows中的所有磁盘列表,也就是【此电脑】里展示的那些盘。我们是通过wmic
来实现的信息获取,命令如下:
wmic logicaldisk get Caption,FreeSpace,Size,VolumeSerialNumber,Description /format:list
运行命令可以得到输出:
Caption=C:
Description=本地固定磁盘
FreeSpace=113127522304
Size=214765137920
VolumeSerialNumber=733C9DDF
Caption=D:
Description=本地固定磁盘
FreeSpace=27744464896
Size=285236793344
VolumeSerialNumber=9A1DD4DB
但是后来,Window11下已经开始默认移除 wmic
这个组件了,意味着我们的应用中不能再使用wmic
这个命令了。。。(微软说:wmic好用哇?好用那就干掉...)
一、使用 Get-PSDrive 获取磁盘列表
考虑到未来wmic
会完全从windows中移除,因此我们现在不再通过wmic
获取了,而是通过命令Get-PSDrive
来获取。
命令如下:
get-psdrive -psprovider filesystem | select-object name,used,free | ConvertTo-Json
在Powershell中执行命令可以得到输出:
[
{
"Name": "C",
"Used": 101637824512,
"Free": 113127313408
},
{
"Name": "D",
"Used": 257558593536,
"Free": 27678199808
}
]
这样,我们就一样的也拿到了磁盘列表。但是这个命令有个问题,看下面。
二、ConvertTo-Json 转换问题
在 powershell 中,ConvertTo-Json
命令有一个很奇特的设定,就是如果你要转换的数据是只有一个元素的数组,那么转换出来的json结果中会直接帮你把这个元素提取出来然后进行转换。原本的数据是数组,这样一来就变成了另外一种数据类型了,在程序中我们一般不希望这样的事情发生。
举个例子:
# 创建一个字符串数组
$testarr1 = @("str1", "str2")
# 将字符串数组转化为JSON
$testarr1 | ConvertTo-Json
# 得到正确的 JSON 数组。
[
"str1",
"str2"
]
上面这个例子中,数组里包含1条以上的数据,转换正常。再看下面的数组只有一条数据时:
# 创建一个字符串数组,只有一个元素
$testarr2 = @("value1")
# 将字符串数组转化为JSON
$testarr2 | ConvertTo-Json
# 得到一个字符串数据,而不是JSON 数组
"value1"
很离谱,这这这....这个特性就会导致我们获取磁盘列表数据时出现问题,当用户电脑里只有一个盘时,我们的命令得到的结果就是一个对象,而不是数组,导致数据解析会出问题。
三、保证 ConvertTo-Json 转换结果统一
要实现 ConvertTo-Json 命令的转换行为总是统一的,有一个十分简便的解决方法,只需要在数组前面加一个,
逗号。
例如:
# 在最前面添加一个 , 逗号
,$testarr1 | ConvertTo-Json
{
"value": [
"str1",
"str2"
],
"Count": 2
}
# 对于只有一条数据的数组,也可以。
,$testarr2 | ConvertTo-Json
{
"value": [
"value1"
],
"Count": 1
}
可以看到,我们的结果中虽然多了几个别的字段,但是我们最终需要的数据都准确的呈现在了 "value" 属性下面。 我们只需要取 value 节点下面的数据即可。
现在我们有了修复方法,针对最开始我的实际业务场景就可以采用下面的代码进行修复了:
,@(get-psdrive -psprovider filesystem | select-object name,used,free) | ConvertTo-Json
在只有一个盘的电脑上运行时,就会得到输出:
{
"value": [
{
"Name": "C",
"Used": 101640720384,
"Free": 113124417536
}
],
"Count": 1
}
!!完美~