【问题标题】:Windows batch file to get C:\ drive total space and free space available获取 C:\ 驱动器总空间和可用空间的 Windows 批处理文件
【发布时间】:2013-06-19 19:20:25
【问题描述】:

我需要一个 bat 文件来获取 Windows 系统中 C:\ 驱动器的总空间和可用空间(以 GB(千兆字节)为单位),并创建一个包含详细信息的文本文件。

注意:我不想使用任何外部实用程序。

【问题讨论】:

  • 我没有看到编程问题(任何与此相关的问题)。即使您改写成一个正确的编程问题,也没有使用本机批处理的解决方案,因为本机批处理无法对您将在今天的磁盘驱动器中看到的大量数字执行数学运算。纯原生批处理可以提供免费字节,但不能提供免费 GB。
  • “外部实用程序”是指您只想使用 Windows(版本?7?)附带的东西,如 fsutil、wmic 等? PowerShell 或 VBScript 呢?它们随 Windows 一起提供。

标签: windows batch-file cmd size volume


【解决方案1】:

将大小按字节截取 9 位,得到以 GB 为单位的大小:

@echo off & setlocal ENABLEDELAYEDEXPANSION
SET "volume=C:"
FOR /f "tokens=1*delims=:" %%i IN ('fsutil volume diskfree %volume%') DO (
    SET "diskfree=!disktotal!"
    SET "disktotal=!diskavail!"
    SET "diskavail=%%j"
)
FOR /f "tokens=1,2" %%i IN ("%disktotal% %diskavail%") DO SET "disktotal=%%i"& SET "diskavail=%%j"
(ECHO(Information for volume %volume%
ECHO(total  %disktotal:~0,-9% GB
ECHO(avail. %diskavail:~0,-9% GB)>size.txt
TYPE size.txt

cmd 只能计算最大为 2^31-1 的数字(2,147,483,647 ~ 2.000001 GB)

【讨论】:

  • 在我的 Win7 机器上,数字后面没有额外的空格或其他字符,所以长度应该是 -9,而不是 -10。此外,这仅近似于 GB。我想你知道这一点,但你的回答可能会误导某些人。
  • 输出取决于本地/区域设置(如 robocopy),我现在将其更改为更“美国风格”。 GB 值在数学上不正确,可能会在 +/- 1GB 范围内变化,这对于小卷更重要。
  • 您可以再添加一个 FOR /F 循环,使用 delims=space 去除值中的前导和尾随空格。那么你的答案就不会受到区域设置的影响。
  • 我不知道为什么我假设尾随字符是一个空格:/?
  • 如果没有额外的尾随字符,无论语言环境如何,那么长度肯定应该是-9。您编辑的代码肯定是错误的。它应该是 %var:~0,-9% 带有额外的 FOR /F,或者 %var:~1,-9% 没有。我假设前导空格在不同语言环境中是恒定的。
【解决方案2】:

这可能根本不是您想要的,因为它使用 PowerShell,但“外部实用程序”有点模糊,给我留下了一些回旋余地。另外,它本质上是单线的。

SETLOCAL

FOR /F "usebackq tokens=1,2" %%f IN (`PowerShell -NoProfile -EncodedCommand "CgBnAHcAbQBpACAAVwBpAG4AMwAyAF8ATABvAGcAaQBjAGEAbABEAGkAcwBrACAALQBGAGkAbAB0AGUAcgAgACIAQwBhAHAAdABpAG8AbgA9ACcAQwA6ACcAIgB8ACUAewAkAGcAPQAxADAANwAzADcANAAxADgAMgA0ADsAWwBpAG4AdABdACQAZgA9ACgAJABfAC4ARgByAGUAZQBTAHAAYQBjAGUALwAkAGcAKQA7AFsAaQBuAHQAXQAkAHQAPQAoACQAXwAuAFMAaQB6AGUALwAkAGcAKQA7AFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAoACQAdAAtACQAZgApACwAJABmAH0ACgA="`) DO ((SET U=%%f)&(SET F=%%g))

@ECHO Used: %U%
@ECHO Free: %F%

由于批处理/CMD 几乎在所有方面都不擅长,因此我决定使用 PowerShell,它适用于此类工作,并且可以快速轻松地访问 WMI。

这是 PowerShell 代码:

Get-WMIObject -Query "SELECT * FROM Win32_LogicalDisk WHERE Caption='C:'" `
  | % { 
      $f = [System.Math]::Round($_.FreeSpace/1024/1024/1024,1);
      $t = [System.Math]::Round($_.Size/1024/1024/1024,1);
      Write-Host ('' + ($t-$f) + ',' + $f);
  }

这会输出用逗号分隔的两个值。现在,如果我们能在 FOR 循环中做到这一点!

PowerShell 有很好的能力接受 Base64 编码的命令(以消除转义和使代码难以阅读的需要),所以我们需要做的就是尽可能缩小这个命令(以减小大小编码的字符串——严格来说是一种精细,不是绝对必要的)。我还将大小减小为整数,将它们四舍五入。它至少比丢弃低位十进制数字更接近。

缩小编码命令并在 PowerShell 中对其进行编码如下所示:

$code = {
gwmi Win32_LogicalDisk -Filter "Caption='C:'"|%{$g=1073741824;[int]$f=($_.FreeSpace/$g);[int]$t=($_.Size/$g);Write-Host ($t-$f),$f}
}
$enc = [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($code))
Write-Host $enc

(有关详细信息,请参阅 PowerShell /?。)

我希望它可以在现有的任何 Win7 或 Win8 机器上运行。 PoSH 代码不依赖任何高级功能(可能除了 EncodedCommand 位),所以如果 PoSH 安装在 XP 或 Vista 机器上,它很有可能工作。我无法谈论 MS 通过 Windows Update 推动 PoSH 的历史,但我认为这很有可能会无处不在。

【讨论】:

    【解决方案3】:

    无论如何都不是一个完整的解决方案,但有人可能会觉得这很有帮助:

    dir | find "bytes"
    

    【讨论】:

      【解决方案4】:

      这应该批量工作:

      for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^C:"') do set space=%%S
      echo %space%
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-15
        • 2013-12-21
        • 2021-01-16
        • 2021-06-20
        • 1970-01-01
        • 1970-01-01
        • 2019-12-12
        • 1970-01-01
        相关资源
        最近更新 更多