Board logo

标题: [数值计算] [已解决]批处理怎样用 fsutil/wmic 计算系统盘已用空间? [打印本页]

作者: aries215    时间: 2018-5-5 07:16     标题: [已解决]批处理怎样用 fsutil/wmic 计算系统盘已用空间?

本帖最后由 aries215 于 2019-1-8 05:43 编辑

我自己找到更可靠的方法,准确,兼容:
http://www.bathome.net/thread-51804-1-1.html
==================================
  1. fsutil volume diskfree c:
复制代码
剩余空间和总空间怎么分别获取?

先前请教了wmic的取值方法,现在想改用简便的fsutil。
谢谢大家热心帮助!
作者: 1410029385    时间: 2018-5-5 08:42

本帖最后由 1410029385 于 2018-5-5 08:44 编辑
  1. $source = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("dXNpbmcgU3lzdGVtO3VzaW5nIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcztwdWJsaWMgY2xhc3MgS2VybmVsMzJ7W0RsbEltcG9ydCgiS2VybmVsMzIuZGxsIildcHJpdmF0ZSBzdGF0aWMgZXh0ZXJuIHZvaWQgR2V0U3lzdGVtRGlyZWN0b3J5KGJ5dGVbXSBieXRlcywgaW50IGxlbmd0aCk7W0RsbEltcG9ydCgiS2VybmVsMzIuZGxsIildcHJpdmF0ZSBzdGF0aWMgZXh0ZXJuIGJvb2wgR2V0RGlza0ZyZWVTcGFjZUV4KHN0cmluZyBwYXRoLCBvdXQgdWxvbmcgbHB1c2UsIG91dCB1bG9uZyBscHRvdGFsLCBvdXQgdWxvbmcgbHBmcmVlKTtwdWJsaWMgc3RhdGljIHVsb25nW10gQ2hlY2tTeXN0ZW1EaXNrRnJlZVNwYWNlKCl7Ynl0ZVtdIHN5c0RpciA9IG5ldyBieXRlWzEyOF07R2V0U3lzdGVtRGlyZWN0b3J5KHN5c0RpciwgMTI4KTtzdHJpbmcgUGF0aCA9IFN5c3RlbS5UZXh0LkVuY29kaW5nLkRlZmF1bHQuR2V0U3RyaW5nKHN5c0RpcikuVHJpbUVuZCgnXDAnKS5TdWJzdHJpbmcoMCwgMyk7dWxvbmcgbHB1c2U7dWxvbmcgbHB0b3RhbDt1bG9uZyBscGZyZWU7R2V0RGlza0ZyZWVTcGFjZUV4KFBhdGgsIG91dCBscHVzZSwgb3V0IGxwdG90YWwsIG91dCBscGZyZWUpO3JldHVybiBuZXdbXSB7IGxwdXNlLCBscHRvdGFsLCBscGZyZWUgfTt9fV=="))
  2. Add-Type $source
  3. $space = [Kernel32]::CheckSystemDiskFreeSpace()
  4. $space = [System.Convert]::ToUInt64(($space[1] - $space[2])/1048576)
  5. Write-Host 系统盘已用空间 $space MB
复制代码

作者: aries215    时间: 2018-5-5 08:58

本帖最后由 aries215 于 2018-5-5 09:13 编辑

回复 2# 1410029385
我要纯批处理哦,否则有些环境执行不了。
谢谢!为啥要转Base64?
作者: tigerpower    时间: 2018-5-5 11:56

本帖最后由 tigerpower 于 2018-5-5 19:29 编辑

纯批,误差在2MB以内:
  1. @echo off
  2. for /f "tokens=2,3" %%i in ('wmic logicaldisk C: get size^,freespace^,caption^|findstr C:') do @set a=%%i&set b=%%j
  3. set /a s=(%b:~0,-3%-%a:~0,-3%)/1024*1000/1024
  4. echo %s%MB
复制代码
要精确值使用powershell:
  1. powershell -c "$c=Get-WmiObject Win32_LogicalDisk -Filter \"DeviceID='C:'\";\"{0:F2}MB\" -f (($c.Size-$c.FreeSpace)/1mb)"
复制代码

作者: aries215    时间: 2018-5-5 18:19

本帖最后由 aries215 于 2018-5-6 19:29 编辑

回复 4# tigerpower
谢谢!但闪退。
Powershell 不是每台电脑都有。结果正确,速度太慢。
作者: tigerpower    时间: 2018-5-5 19:20

本帖最后由 tigerpower 于 2018-5-5 19:28 编辑

回复 5# aries215

纯批的代码已改,误差在2MB以内,如果在意这点误差,可以搜一下论坛里“大数”和“浮点数”的帖子。
Powershell第一次运行是比较慢,之后和纯批的速度差距不超过1秒。
作者: aries215    时间: 2018-5-5 19:24

本帖最后由 aries215 于 2018-5-6 19:29 编辑

回复 6# tigerpower
结果正确!
再次感谢!
作者: codegay    时间: 2018-5-6 13:23





用nim写了一个,表示很开心:
  1. type
  2.     WINBOOL* = uint32
  3.     s64* = uint64
  4. proc  getDiskFreeSpaceEx*(name: cstring, freeBytes,
  5.     lpTotalNumberOfBytes,lpTotalNumberOfFreeBytes: var s64): WINBOOL
  6.     {.stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExA", discardable.}
  7. proc getusedspace*(name: cstring):auto {.discardable.} =
  8.     var freeBytes, totalBytes, totalFreeBytes: s64
  9.     getDiskFreeSpaceEx(name, freeBytes, totalBytes,totalFreeBytes)
  10.     result = ((totalBytes - freeBytes) div 1024 div 1024)
  11. echo "已经使用:", getusedspace("c:\\EFI"), "MB"
复制代码

作者: aries215    时间: 2018-5-6 19:29

回复 8# codegay
谢谢,虽然看不懂
作者: tigerpower    时间: 2018-5-6 22:42

发现一个更简单的
  1. powershell -c (gdr C).Used/1mb
复制代码

作者: aries215    时间: 2019-1-5 19:23

顶起,有新问题!
作者: aries215    时间: 2019-1-5 19:26

回复 4# tigerpower
拜托!
1楼有新问题!
作者: 523066680    时间: 2019-1-5 20:13

本帖最后由 523066680 于 2019-1-5 20:27 编辑

回复 1# aries215


    你想要第一列和最后一列是吗?
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. for /f "tokens=1,3" %%i in ('fsutil volume diskfree c:') do (
  4.     set "a=%%i"
  5.     set "b=%%j"
  6.     echo !a! - !b!
  7. )
复制代码
蛋疼一点:
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. :: 常量初始化
  4. set sharp=####################
  5. :get_total_size
  6. for /f "tokens=3" %%i in ('fsutil volume diskfree c:') do (set total=%%i&goto :get_free_size)
  7. :get_free_size
  8. for /f "tokens=3" %%i in ('fsutil volume diskfree c: ^|more +1') do (set free=%%i&goto :count)
  9. :count
  10. call :bignum_minus %total% %free% delta
  11. echo %total% %free% 已用空间 %delta%
  12. exit /b
  13. ::大数减法
  14. :bignum_minus
  15.     setlocal
  16.     set num_a=%1
  17.     set num_b=%2
  18.     call :length %num_a% len_a
  19.     call :length %num_b% len_b
  20.     set /a max = len_a
  21.     if %len_b% gtr %len_a% (set /a max=len_b, len_b=len_a&set num_a=%num_b%&set num_b=%num_a%)
  22.     set /a minus = 0
  23.     for /l %%n in ( 1, 1, %max% ) do (
  24.         if %%n leq %len_b% (
  25.             set /a dt = !num_a:~-%%n,1! - !num_b:~-%%n,1! - minus
  26.         ) else (
  27.             set /a dt = !num_a:~-%%n,1! - minus
  28.         )
  29.         if !dt! lss 0 (
  30.             set /a buff[%%n] = dt + 10, minus=1
  31.         ) else (
  32.             set /a buff[%%n] = dt, minus=0
  33.         )
  34.     )
  35.     set delta=#
  36.     for /l %%a in (%max%, -1, 1) do set delta=!delta:#0=#!!buff[%%a]!
  37.     endlocal &set %3=%delta:#=%
  38.     goto :eof
  39. ::字符串长度计算
  40. :length %str% %vname%
  41.     setlocal
  42.     set test=%~1_%sharp%
  43.     set test=!test:~0,20!
  44.     set test=%test:*_=%
  45.     set /a len=20-(%test:#=1+%1)
  46.     endlocal &set %2=%len%
  47.     goto :eof
复制代码
如果你要我转换成 KB MB GB ,对不起,我不会批处理,我是论坛消遣区负责灌水的。
作者: aries215    时间: 2019-1-5 20:43

本帖最后由 aries215 于 2019-1-5 20:48 编辑

回复 13# 523066680
我要的是总空间和剩余空间,分别赋值,要相减得出系统占用大小。
谢谢
作者: Batcher    时间: 2019-1-5 20:58

回复 14# aries215
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. for /f "tokens=1,3" %%i in ('fsutil volume diskfree c:') do (
  4.     if "%%i" equ "可用字节总数" (
  5.         set "free=%%j"
  6.     ) else if "%%i" equ "字节总数" (
  7.         set "total=%%j"
  8.     )
  9. )
  10. echo !free!
  11. echo !total!
  12. pause
复制代码

作者: aries215    时间: 2019-1-5 21:05

本帖最后由 aries215 于 2019-1-5 21:08 编辑

回复 15# Batcher
结果正确!
如果不带汉字,以便适应不同语言,可以吗?
谢谢!
作者: Batcher    时间: 2019-1-5 21:13

回复 16# aries215
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. set n=1
  4. for /f "tokens=1,3" %%i in ('fsutil volume diskfree c:') do (
  5.     if !n! equ 1 (
  6.         set "free=%%j"
  7.     ) else if !n! equ 2 (
  8.         set "total=%%j"
  9.     )
  10.     set /a n+=1
  11. )
  12. echo !free!
  13. echo !total!
  14. pause
复制代码

作者: aries215    时间: 2019-1-5 21:18

回复 17# Batcher
请问能讲解一下吗?谢谢!
作者: Batcher    时间: 2019-1-5 21:25

回复 18# aries215


    具体哪里不懂?for命令的语法可以参考:
http://bbs.bathome.net/thread-31727-1-1.html
http://bbs.bathome.net/thread-2189-1-1.html
作者: aries215    时间: 2019-1-5 21:28

本帖最后由 aries215 于 2019-1-5 22:42 编辑

回复 19# Batcher
我再好好看看
作者: 523066680    时间: 2019-1-6 09:23

本帖最后由 523066680 于 2019-1-6 09:24 编辑

回复 20# aries215

    不是还要做减法吗,13楼第二段代码做了减法

Stackoverflow有一个很好的方案,结果也很直观
https://stackoverflow.com/questi ... ote-windows-servers
  1. >diskfree.cmd %COMPUTERNAME% C:
  2. Total space: 137GB
  3. Free space: 44GB
  4. Used space: 93GB
  5. Percent Used: 67%
  6. Percent Free: 33%
复制代码

作者: aries215    时间: 2019-1-6 20:03

回复 21# 523066680
谢谢!想找更简单通用的方式呢。
作者: aries215    时间: 2019-1-7 20:00

回复 1# aries215
顶起!路过的大侠帮帮忙吧,谢谢!
作者: aries215    时间: 2019-1-7 20:53

回复 13# 523066680
谢谢你热心帮助!
你第二组代码,运行的结果是:
命令行参数过多。
命令语法不正确。
241289846784  已用空间

能否两次除以1048再得出结果?
作者: 523066680    时间: 2019-1-7 20:57

本帖最后由 523066680 于 2019-1-7 21:00 编辑

回复 24# aries215

    是可以简化处理的,但是我很懒,在win7运行挺正常的。
为什么是1048不是1024
作者: aries215    时间: 2019-1-7 21:02

回复 25# 523066680
1024谁都知道,但1048更接近实际看到的GB数值。
13楼的 :get_free_size 不存在?!
作者: aries215    时间: 2019-1-7 21:08

本帖最后由 aries215 于 2019-1-7 21:12 编辑

回复 17# Batcher
请问,为何有些10PE里,两者相减会提示“找不到操作数”:
  1. set /a "SystemSize=!total:~0,-6!-!free:~0,-6!"
复制代码
搜索过“大数”,太复杂了。
请问有无稍微简练的(纯批处理)计算方式?
作者: 523066680    时间: 2019-1-7 21:12

本帖最后由 523066680 于 2019-1-7 21:29 编辑

回复 26# aries215

不懂批处理,按零请高明



我发现我把total 和 free写反了,win7测试勉强OK,不知道有没有其他BUG
  1. @echo off
  2. SetLocal EnableDelayedExpansion
  3. :: 常量初始化
  4. set const=9876543210
  5. :get_free_size
  6. for /f "tokens=3" %%i in ('fsutil volume diskfree c:') do (set free=%%i&goto :get_total_size)
  7. :get_total_size
  8. for /f "tokens=3" %%i in ('fsutil volume diskfree c: ^|more +1') do (set total=%%i&goto :count)
  9. :count
  10. set /a Afoo=%total:~0,-5%, Abar=%total:~-5%
  11. set /a Bfoo=%free:~0,-5%, Bbar=%free:~-5%
  12. echo %Afoo% %Abar% %Bfoo% %Bbar%
  13. set /a foo=Afoo-Bfoo, bar=Abar-Bbar
  14. if %bar% leq 0 set /a foo-=1, bar=100000-(-bar)
  15. echo,
  16. echo %total% %free% 已用空间 %foo%%bar%
  17. exit /b
复制代码

作者: aries215    时间: 2019-1-7 21:13

回复 28# 523066680
隐藏太深~
作者: Batcher    时间: 2019-1-7 22:48

回复 27# aries215


    没有。如果有的话,大家也就不用写那些复杂的代码了
作者: aries215    时间: 2019-1-8 05:41

本帖最后由 aries215 于 2019-1-10 07:21 编辑

回复 30# Batcher
我找到了Diskpart的方法,请看6楼回帖:
http://bbs.bathome.net/thread-51804-1-1.html
http://www.bathome.net/thread-51804-1-1.html




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2