Reputation: 1356
I want to make an action in a batch file dependent on my free storage space, but it fails (interestingly only sometimes), because the free space is more than 2GB, making the variable not settable.
This is the batch file:
cd "C:\Users\Fabian\Desktop\Screen Recordings\Auto"
for /F "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace /format:value`) do (set FreeSpace=%%x)
if (%FreeSpace%) LSS (2499522027520) (
for /F "delims=" %%a in ('dir /b /a-d /t:w /o:d "C:\Users\Fabian\Desktop\Screen Recordings\Auto\*.flv"') do (
del "%%a"
goto :breakLoop
))
:breakLoop
exit
A lot of this is just workarounds for Windows' weirdnesses, the important part is: set FreeSpace=%%x
That x
is a string straight out of the live disk data, which should be converted to a number, but since it's bigger than 232, that fails (and it makes it a string, making the comparison in the next line a string comparison, which is not at all what I want).
I can also not divide it by a number, because that would require it being a number first.
Would I have to use the gross hack of chopping off digits at the end by changing the length of the string (if yes, how?) or is there a way to have proper long
numbers in a batch file?
I found this script (archive) that actually works, but I don't know how. Which part of it chops off the digits and which is the important part that I need? I can't let it sum up all folder sizes every time, because the script runs every 20 seconds.
Upvotes: 4
Views: 2621
Reputation: 34949
It is not possible in Windows command prompt to handle numbers outside of the range of signed 32-bit integers which range from -231 = -2147483648 to 231 - 1 = 2147483647.
You could however remove a couple of digits using sub-string expansion, say 6, on the right to have a rounded-down number of Mega-Bytes instead of Bytes and use the result for a numeric comparison, like this:
cd "%USERPROFILE%\Desktop\Screen Recordings\Auto"
set "FreeSpace=0"
for /F "usebackq skip=1" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace^,Size`) do (set "FreeSpace=%%x")
rem // Remove the last 6 digits to get MBytes:
set "FreeSpaceMB=%FreeSpace:~,-6%"
rem // Ensure to not leave an empty value behind:
if not defined FreeSpaceMB set "FreeSpaceMB=0"
if %FreeSpaceMB% LSS 2499522 (
for /F "delims=" %%a in ('dir /B /A:-D /T:W /O:D "C:\Users\Fabian\Desktop\Screen Recordings\Auto\*.flv"') do (
del "%%a"
goto :breakLoop
)
)
:breakLoop
exit /B
Of course you lose precision but this could probably be acceptable for the purpose at hand.
I also changed the for /F
loop that captures the wmic
output in order to avoid Unicode conversion artefacts like orphaned carriage-return (CR) characters, which would result in the variable FreeSpace
to contain a number plus a CR. That is why I queried also the value Size
although it is not needed, but so the FreeSpace
value is not the last one which might be tailed by a CR.
By the way, note that I removed the superfluous parentheses from the if
command line.
Upvotes: 2