[SOLVED] Get TRUE HDD data as opposed to CAPACITY data.

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
PAB
Posts: 57
Joined: 12 Aug 2019 13:57

[SOLVED] Get TRUE HDD data as opposed to CAPACITY data.

#1 Post by PAB » 06 Nov 2019 07:03

Good afternoon,

After something I was doing yesterday and Steffen managed to sort out for me, I noticed that what I did a few days ago was actually incorrect. It is getting the true size of the HDD as opposed to the capacity.

This is the code that works but gives the capacity rather than the true size because I need to get the result divided by /1024*1000/1024/1024 according to my research and to TWO decimal places.

Code: Select all

Set "Volume=C:"
For /f "Tokens=1*Delims=:" %%i In ('fsutil Volume DiskFree %SystemDrive%') Do (
    Set "PC_Volume=!PC_DiskTotal!"
    Set "PC_DiskTotal=!PC_DiskFree!"
    Set "PC_DiskFree=%%j"
)
Set /a PC_DiskUsed=%PC_DiskTotal:~0,-9% - %PC_DiskFree:~0,-9%

echo %systemdrive% Partition Size:        %PC_DiskTotal:~0,-9% GB
echo %systemdrive% Partition Used:         %PC_DiskUsed% GB
echo %systemdrive% Partition Free:        %PC_DiskFree:~0,-9% GB
Now I have tried this amongst many others . . .

Code: Select all

SetLocal EnableDelayedExpansion

:: PC HDD Partition Size
Set "Volume=C:"
For /f "Tokens=1*Delims=:" %%i In ('fsutil Volume DiskFree %SystemDrive%') Do (
    Set "PC_Volume=!PC_DiskTotal!"
    Set "PC_DiskTotal=!PC_DiskFree!"
    Set "PC_DiskFree=%%j"
)
Set /a PC_DiskUsed=%PC_DiskTotal:~0,-9/1024*1000/1024/1024% - %PC_DiskFree:~0,-9/1024*1000/1024/1024%

echo %systemdrive% Partition Size:        %PC_DiskTotal:~0,-9/1024*1000/1024/1024%
echo %systemdrive% Partition Used:         %PC_DiskUsed/1024*1000/1024/1024%
echo %systemdrive% Partition Free:        %PC_DiskFree:~0,-9/1024*1000/1024/1024%
. . . and this . . .

Code: Select all

SetLocal EnableDelayedExpansion
Set "Volume=C:"

For /f "Tokens=2 Delims=:" %%a In ('fsutil Volume DiskFree C: ^| Find /i "avail free"') Do Set bytes=%%a
set /a Calc_True=%bytes:~0,-3%/1024*1000/1024/1024

For /f "Tokens=1*Delims=:" %%i In ('fsutil Volume DiskFree %SystemDrive%') Do (

   set /a Calc_True="/1024*1000/1024/1024"

   Set /a "PC_Volume=PC_Volume / %Calc_True%"
   Set /a "PC_DiskTotal=PC_DiskTotal / %Calc_True%"
   Set /a "PC_DiskFree=PC_DiskFree / %Calc_True%"

   Set "PC_Volume=!PC_DiskTotal!"
   Set "PC_DiskTotal=!PC_DiskFree!"
   Set "PC_DiskFree=%%j"
)
   Set /a "PC_DiskFree=PC_DiskFree / %Calc_True%"
   Set /PC_DiskUsed=%PC_DiskTotal:~0,-9% - %PC_DiskFree:~0,-9%

echo %systemdrive% Partition Size:        %PC_DiskTotal%
echo %systemdrive% Partition Used:         %PC_DiskUsed%
echo %systemdrive% Partition Free:        %PC_DiskFree:~0,-9%
I will not list them.

Thanks in advance.
Last edited by PAB on 07 Nov 2019 09:34, edited 1 time in total.

aGerman
Expert
Posts: 3763
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Get TRUE HDD data as opposed to CAPACITY data.

#2 Post by aGerman » 06 Nov 2019 10:54

Batch is by far the worst language to do things like that. You can't calculate with numbers having decimals because numbers in Batch are integers only. And since the type size of this integer is limited to 32 bits you can't even process the volume size in bytes because 2147483647 is the greatest value that is still recognized as number.

The workaround is quite complicated. I can't recall what member of this forum developed the algorithm and I can't find the related thread anymore. However, that's how you could get the values you're after using pure Batch. Note that subroutines :output and :B2GiB have to appear below of your main code and that your main code has to be finished using either exit /b or goto :eof.

Code: Select all

@echo off &setlocal
for /f "skip=1 delims=" %%i in ('WMIC logicaldisk WHERE "DeviceID='%systemdrive%'" GET FreeSpace^,Size') do (
  for /f "tokens=1,2" %%j in ("%%i") do call :output %%j %%k
)
pause
exit /b

:output
call :B2Gib %1
set "free=%errorlevel%"
call :B2Gib %2
set "size=%errorlevel%"
set /a "used=size-free, nUsed=used*50/size, nFree=50-nUsed"
set "size=      %size:~0,-2%.%size:~-2%"
set "used=      %used:~0,-2%.%used:~-2%"
set "free=      %free:~0,-2%.%free:~-2%"

echo Size: %size:~-10% GB
echo Used: %used:~-10% GB
echo Free: %free:~-10% GB
exit /b

:B2GiB
set "B=%~1"
set "highPart=%B:~0,-6%"
set "lowPart=%B:~-6%"
set /a "KB = highPart / 1024 * 1000000, borrow = highPart %% 1024"
if %borrow% gtr 0 (
  set "lowPart=%borrow%%lowPart%""
) else (
  for /l %%a in (1,1,5) do if "!lowPart:~0,1!" equ "0" set "lowPart=!lowPart:~1!"
)
set /a "KB += lowPart / 1024, GB = KB / 1048576, HH = KB %% 1048576 * 100 / 1048576"
if %HH% lss 10 set "HH=0%HH%"
exit /b %GB%%HH%
Steffen

PAB
Posts: 57
Joined: 12 Aug 2019 13:57

Re: Get TRUE HDD data as opposed to CAPACITY data.

#3 Post by PAB » 06 Nov 2019 12:26

Thank you.

When I put it in a batch file of it's own it works.
I have tried to implement your instructions but I can't get it to work, it exits the cmd prompt and doesn't create the output file! Here is some cut down code with your code included . . .

Code: Select all

@echo off
SetLocal EnableDelayedExpansion

Set OUTPUT=%userprofile%\Desktop\test.txt
If EXIST "%OUTPUT%" Del "%OUTPUT%"

setlocal
for /f "skip=1 delims=" %%i in ('WMIC logicaldisk WHERE "DeviceID='%systemdrive%'" GET FreeSpace^,Size') do (
  for /f "tokens=1,2" %%j in ("%%i") do call :output %%j %%k
)
rem pause
exit /b

:: =================================================================================

echo Size: %size:~-10% GB >> %OUTPUT%
echo Used: %used:~-10% GB >> %OUTPUT%
echo Free: %free:~-10% GB >> %OUTPUT%
exit /b

:: =================================================================================

echo. >> "%OUTPUT%"
echo Created: ^
%date:~0,2%-%date:~3,2%-%date:~6,4% at ^
%time:~0,2%:%time:~3,2%:%time:~6,2%. >> "%OUTPUT%"

echo ^< Press ANY key to Exit ^> & Pause > NUL
Goto :EOF
:EOF

:output
call :B2Gib %1
set "free=%errorlevel%"
call :B2Gib %2
set "size=%errorlevel%"
set /a "used=size-free, nUsed=used*50/size, nFree=50-nUsed"
set "size=      %size:~0,-2%.%size:~-2%"
set "used=      %used:~0,-2%.%used:~-2%"
set "free=      %free:~0,-2%.%free:~-2%"

rem echo Size: %size:~-10% GB
rem echo Used: %used:~-10% GB
rem echo Free: %free:~-10% GB
exit /b

:B2GiB
set "B=%~1"
set "highPart=%B:~0,-6%"
set "lowPart=%B:~-6%"
set /a "KB = highPart / 1024 * 1000000, borrow = highPart %% 1024"
if %borrow% gtr 0 (
  set "lowPart=%borrow%%lowPart%""
) else (
  for /l %%a in (1,1,5) do if "!lowPart:~0,1!" equ "0" set "lowPart=!lowPart:~1!"
)
set /a "KB += lowPart / 1024, GB = KB / 1048576, HH = KB %% 1048576 * 100 / 1048576"
if %HH% lss 10 set "HH=0%HH%"
exit /b %GB%%HH%

Kind regards, Paul

aGerman
Expert
Posts: 3763
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Get TRUE HDD data as opposed to CAPACITY data.

#4 Post by aGerman » 06 Nov 2019 13:18

Any exit /b or goto :eof in your main code will lead to leave the script processing. (FWIW goto :eof is for "go to end of file", no actual :eof label necessary.) That's why I wrote that you need it at the end of the main code.

Code: Select all

@echo off
SetLocal EnableDelayedExpansion

Set OUTPUT=%userprofile%\Desktop\test.txt
If EXIST "%OUTPUT%" Del "%OUTPUT%"

setlocal
for /f "skip=1 delims=" %%i in ('WMIC logicaldisk WHERE "DeviceID='%systemdrive%'" GET FreeSpace^,Size') do (
  for /f "tokens=1,2" %%j in ("%%i") do call :output %%j %%k
)

:: =================================================================================

echo Size: %size:~-10% GB >> %OUTPUT%
echo Used: %used:~-10% GB >> %OUTPUT%
echo Free: %free:~-10% GB >> %OUTPUT%

:: =================================================================================

echo. >> "%OUTPUT%"
echo Created: ^
%date:~0,2%-%date:~3,2%-%date:~6,4% at ^
%time:~0,2%:%time:~3,2%:%time:~6,2%. >> "%OUTPUT%"

echo ^< Press ANY key to Exit ^> & Pause > NUL
Goto :EOF



:output
call :B2Gib %1
set "free=%errorlevel%"
call :B2Gib %2
set "size=%errorlevel%"
set /a "used=size-free"
set "size=      %size:~0,-2%.%size:~-2%"
set "used=      %used:~0,-2%.%used:~-2%"
set "free=      %free:~0,-2%.%free:~-2%"
exit /b

:B2GiB
set "B=%~1"
set "highPart=%B:~0,-6%"
set "lowPart=%B:~-6%"
set /a "KB = highPart / 1024 * 1000000, borrow = highPart %% 1024"
if %borrow% gtr 0 (
  set "lowPart=%borrow%%lowPart%""
) else (
  for /l %%a in (1,1,5) do if "!lowPart:~0,1!" equ "0" set "lowPart=!lowPart:~1!"
)
set /a "KB += lowPart / 1024, GB = KB / 1048576, HH = KB %% 1048576 * 100 / 1048576"
if %HH% lss 10 set "HH=0%HH%"
exit /b %GB%%HH%

Aacini
Expert
Posts: 1619
Joined: 06 Dec 2011 22:15
Location: México City, México

Re: Get TRUE HDD data as opposed to CAPACITY data.

#5 Post by Aacini » 06 Nov 2019 13:34

Perhaps this answer may help you...

Antonio

PAB
Posts: 57
Joined: 12 Aug 2019 13:57

Re: [SOLVED] Get TRUE HDD data as opposed to CAPACITY data.

#6 Post by PAB » 07 Nov 2019 09:40

Thank you BOTH.

Post Reply