I need a script to copy a specific image depending on the screen resolution being used.
so far I've found that wmic desktopmonitor get screenheight is giving me the appropriate output but i'm having trouble parsing it to a useable variable
the problem is that the output is on three lines and I only need the information from the second one.
Can anyone help?
#Stephan's answer modified to be compatible with all windows versions (including Windows 8):
setlocal
for /f %%i in ('wmic path Win32_VideoController get CurrentHorizontalResolution^,CurrentVerticalResolution /value ^| find "="') do set "%%i"
echo your screen is %CurrentHorizontalResolution% * %CurrentVerticalResolution% pixels
You can even get more parameters with one single wmic:
for /f %%i in ('wmic desktopmonitor get screenheight^,screenwidth /value ^| find "="') do set "%%f"
echo your screen is %screenwidth% * %screenheight% pixels
If you need to have your own variablenames, it's a bit more complicated:
for /f "tokens=1,2 delims==" %%i in ('wmic desktopmonitor get screenheight^,screenwidth /value ^| find "="') do (
if "%%i"=="ScreenHeight" set height=%%j
if "%%i"=="ScreenWidth" set width=%%j
)
echo your screen is %width% * %height% pixels
if you need only one value:
for /f "tokens=2 delims==" %%i in ('wmic desktopmonitor get screenheight /value ^| find "="') do set height=%%i
echo %height%
for /f "tokens=*" %%f in ('wmic desktopmonitor get screenheight /value ^| find "="') do set "%%f"
echo %size%
pause
Related
I am learning to code the BATCH,
I would like to make a small .bat executable to retrieve various information on computers that I reinstall, to avoid having to navigate through several sections of the windows control panel.
I have already managed to retrieve some information using "for /f", but I must admit that I still don't understand how this command works.
I haven't found any more info on what I'm looking for, so I'm asking for help which would be very welcome.
I'm not looking for a copy/paste solution, I'd like someone to explain my mistake and help me solve it so I can better understand where I went wrong.
Anyway, after reading this indigestible pamphlet, here are the commands I'm looking to run:
for /f "tokens=2 delims==" %%I in (
'wmic LOGICALDISK where DriveType!=4 get DeviceID /value'
) do for /f "delims=" %%# in ("%%I") do set "deviceid=%%~#"
for /f "tokens=2 delims==" %%I in (
'wmic LOGICALDISK where drivetype!=4 get description /value'
) do for /f "delims=" %%# in ("%%I") do set "description=%%~#"
for /f "tokens=2 delims==" %%I in (
'wmic LOGICALDISK where drivetype!=4 get volumename /value'
) do for /f "delims=" %%# in ("%%I") do set "volumename=%%~#"
for /f "tokens=2 delims==" %%I in (
'wmic LOGICALDISK where drivetype!=4 get Size /value'
) do for /f "delims=" %%# in ("%%I") do set "Size=%%~#"
and this is what I get back:
C:\Users\rv\Desktop>for /F "tokens=2 delims==" %I in ('wmic LOGICALDISK where DriveType! 4 get DeviceID /value') do for /F "delims=" %# in ("%I") do set "deviceid=%~#"
4 - Verbe de l'alias non valide.
C:\Users\rv\Desktop>for /F "tokens=2 delims==" %I in ('wmic LOGICALDISK where drivetype! 4 get description /value') do for /F "delims=" %# in ("%I") do set "description=%~#"
4 - Verbe de l'alias non valide.
C:\Users\rv\Desktop>for /F "tokens=2 delims==" %I in ('wmic LOGICALDISK where drivetype! 4 get volumename /value') do for /F "delims=" %# in ("%I") do set "volumename=%~#"
4 - Verbe de l'alias non valide.
C:\Users\rv\Desktop>for /F "tokens=2 delims==" %I in ('wmic LOGICALDISK where drivetype! 4 get Size /value') do for /F "delims=" %# in ("%I") do set "Size=%~#"
4 - Verbe de l'alias non valide.
I think this is due to a misuse of "tokens=" and "delims=" on my part ?
Mmm... I used to think/solve this type of problems in "opposite order"... Please, follow me.
I started typing this command at the command-prompt:
C:\> wmic LOGICALDISK where DriveType!=4 get DeviceID /value
DeviceID=C:
DeviceID=D:
Ok. I always try to make things in an efficient way. If I can get the same result from a single command instead of 4 commands, then I always opted for the single one:
C:\> wmic LOGICALDISK where DriveType!=4 get DeviceID,Description,VolumeName,Size /value
Description=Local Fixed Disk
DeviceID=C:
Size=982768414720
VolumeName=Windows
Description=Local Fixed Disk
DeviceID=D:
Size=16111366144
VolumeName=RECOVERY
Good! In order to "get" such values, we need to execute the wmic command from a for /F command, so I wrote this simple Batch file at first:
for /F "delims=" %%a in ('wmic LOGICALDISK where DriveType!=4 get DeviceID,Description,VolumeName,Size /value') do #echo [%%a]
... and the problems started:
C:\> for /F "delims=" %a in ('wmic LOGICALDISK where DriveType! 4 get DeviceID Description VolumeName Size /value') do #echo [%a]
4 - Verbo de alias no válido.
If you compare the source line vs. the executed command, you'll realize that the equal-sign and the commas disappeared! This happens because these characters: = , ; works as separators for items in most commands (besides space and TAB). This is this way just because MS (Microsoft) decided that... :(
There are two ways to solve this problem: individually caret-^escape each one of these characters OR enclose the whole command in quotes. I choose the second method because it is simpler:
for /F "delims=" %%a in ('"wmic LOGICALDISK where DriveType!=4 get DeviceID,Description,VolumeName,Size /value"') do #echo [%%a]
And the output is:
C:\> for /F "delims=" %a in ('"wmic LOGICALDISK where DriveType!=4 get DeviceID,Description,VolumeName,Size /value"') do #echo [%a]
]
]
]Description=Local Fixed Disk
]DeviceID=C:
]Size=982768414720
]VolumeName=Windows
]
]
]Description=Local Fixed Disk
]DeviceID=D:
]Size=16111366144
]VolumeName=RECOVERY
]
]
]
So far so good, we have solved the equal-sign and comma problem... However, a new problem arises: the lines we think were empty really contain a CR character! There are a couple methods to solve this new point, and the one you used before is the simplest one: process the wmic output lines in a second FOR command:
for /F "delims=" %%a in (
'"wmic LOGICALDISK where DriveType!=4 get DeviceID,Description,VolumeName,Size /value"'
) do #(
for /F "delims=" %%b in ("%%a") do #echo [%%b]
)
And the output is:
C:\> for /F "delims=" %a in ('"wmic LOGICALDISK where DriveType!=4 get DeviceID,Description,VolumeName,Size /value"') do #(for /F "delims=" %b in ("%a") do #echo [%b]
)
[Description=Local Fixed Disk]
[DeviceID=C:]
[Size=982768414720]
[VolumeName=Windows]
[Description=Local Fixed Disk]
[DeviceID=D:]
[Size=16111366144]
[VolumeName=RECOVERY]
Perfect! Now, that we are sure that the code will process the values we want, we insert an #echo off command at beginning and split each line in two parts, the variable and its value:
#echo off
for /F "delims=" %%a in (
'"wmic LOGICALDISK where DriveType!=4 get DeviceID,Description,VolumeName,Size /value"'
) do (
for /F "tokens=1,2 delims==" %%b in ("%%a") do echo [%%b=%%c]
)
The output is the same than before.
Finally, we insert code to save the value of each variable and process all variables each time that a group is complete; that is:
#echo off
setlocal EnableDelayedExpansion
set "VolumeName="
for /F "delims=" %%a in (
'"wmic LOGICALDISK where DriveType^!=4 get DeviceID,Description,VolumeName,Size /value"'
) do (
for /F "tokens=1,2 delims==" %%b in ("%%a") do set "%%b=%%c"
if defined VolumeName (
echo/
echo ===== New disk =====
echo Description=!Description!
echo DeviceID=!DeviceID!
echo Size=!Size!
echo VolumeName=!VolumeName!
set "VolumeName="
)
)
The final output:
===== New disk =====
Description=Local Fixed Disk
DeviceID=C:
Size=982768414720
VolumeName=Windows
===== New disk =====
Description=Local Fixed Disk
DeviceID=D:
Size=16111366144
VolumeName=RECOVERY
Note that in the last code the exclamation-mark needs to be ^escaped. This is because the EnableDelayedExpansion setlocal's option enables the ! as a method to expand variables additional to the %standard% one. You can find a lot of questions/answers about this topic in this site...
How-to: Escape Characters, Delimiters and Quotes at the Windows command line.
In Windows cmd/batch scripting, parameters are most often separated by spaces, but any of the following are also valid delimiters:
, (U+002C, Comma)
; (U+003B, Semicolon)
= (U+003D, Equals Sign)
(U+0020, Space)
␉ (U+0009, Character Tabulation)
You need to escape the Equals Sign in DriveType!=4. Use any of the following:
"DriveType!=4" (using "Double Quotes")
DriveType!^=4 (using common escape character ^ (U+005E, Circumflex Accent))
This batch code retrieves the screen width and screen height, in the format "WIDTH x HEIGHT"
#echo off
setlocal
for /f %%A in ('wmic path Win32_VideoController get CurrentHorizontalResolution^,CurrentVerticalResolution /value ^| find "="') do set "%%A"
echo %CurrentHorizontalResolution% x %CurrentVerticalResolution%
Now, given the output of the above returns "1920 x 1080", the below VBScript Code should spawn an InputBox in the lower-right corner of the screen.
InputBox "","Title","",1920,1080
However, it doesn't. This is because the PosX and PosY variables in the VBS InputBox function are measured in Twips instead of Pixels.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.interaction.inputbox?view=netframework-4.8
Is there any way to convert Pixels to Twips with only Batch and VBScript?
I came across a solution while creating an error message customization program. The idea is to take a second pair of values from WMIC, known as "PixelsPerXLogicalInch" and "PixelsPerYLogicalInch"
for /f %%A in ('wmic path Win32_DesktopMonitor get PixelsPerXLogicalInch^,PixelsPerYLogicalInch /value ^| find "="') do set "%%A"
echo %PixelsPerXLogicalInch% x %PixelsPerYLogicalInch%
This will output a conversion factor for converting pixels to inches. Since a twip is just 1/1440th of an inch, dividing these values into 1440 will result in the number of twips per pixel.
for /f %%A in ('wmic path Win32_DesktopMonitor get PixelsPerXLogicalInch^,PixelsPerYLogicalInch /value ^| find "="') do set "%%A"
set /a TwipsPerPixelX=1440/%PixelsPerXLogicalInch%
set /a TwipsPerPixelY=1440/%PixelsPerYLogicalInch%
echo %TwipsPerPixelX% x %TwipsPerPixelY%
Now, just apply those conversion factors to the positional calculations with a little multiplication.
#echo off
setlocal
for /f %%A in ('wmic path Win32_VideoController get CurrentHorizontalResolution^,CurrentVerticalResolution /value ^| find "="') do set "%%A"
for /f %%A in ('wmic path Win32_DesktopMonitor get PixelsPerXLogicalInch^,PixelsPerYLogicalInch /value ^| find "="') do set "%%A"
set /a TwipX=%CurrentHorizontalResolution%*(1440/%PixelsPerXLogicalInch%)
set /a TwipY=%CurrentVerticalResolution%*(1440/%PixelsPerYLogicalInch%)
echo %TwipX% x %TwipY%
The output values from this set of commands will produce an InputBox just beyond the screen's bottom right corner (as windows are positioned from the top left corner.)
Taking all that into account, you could create a script that spawns an InputBox in a random position on-screen. That, or prompt the user for a position value, or even use this in your own CMD/VBS applications to position your Input Boxes more accurately.
<!-- :
#echo off
setlocal
for /f %%A in ('wmic path Win32_VideoController get CurrentHorizontalResolution^,CurrentVerticalResolution /value ^| find "="') do set "%%A"
for /f %%A in ('wmic path Win32_DesktopMonitor get PixelsPerXLogicalInch^,PixelsPerYLogicalInch /value ^| find "="') do set "%%A"
set /a RandX=(%Random%*%CurrentHorizontalResolution%/32768)*(1440/%PixelsPerXLogicalInch%)
set /a RandY=(%Random%*%CurrentVerticalResolution%/32768)*(1440/%PixelsPerYLogicalInch%)
start /b cscript //nologo "%~f0?.wsf" "%RandX%" "%RandY%"
exit /b
-->
<job><script language="VBScript">
InputBox "","Randomly-Positioned Input Box","",Wscript.Arguments(0),Wscript.Arguments(1)
</script></job>
I did on a lot of windows 10 tablets a shutdown check when the power in the room switched off. Now I tried to update a view dell 8.1 tablets, but the Battery.PowerOnline returns always false. Any ideas?
FOR /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryStatus Get PowerOnline^,RemainingCapacity /Format:list ^| FIND "="') DO SET Battery.%%A
FOR /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryRuntime Get EstimatedRuntime /Format:list ^| FIND "="') DO SET Battery.%%A
FOR /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryFullChargedCapacity Get FullChargedCapacity /Format:list ^| FIND "="') DO SET Battery.%%A
IF /I "%Battery.PowerOnline%"=="TRUE" (
SET doShutDown=0
) ELSE (
SET doShutDown=1
)
You set Battery.%%A which will not set anything to be honest, also, you never defined %Battery.PowerOnline% variable, so it will never return true. Do we really need to check each status? Only the last set from your three commands will keep the variable value, so rather check the main poweronline value and do something from there. Notice how I set the variables:
#echo off
for /F "tokens=* delims=" %%A IN ('WMIC /NameSpace:"\\root\WMI" Path BatteryStatus Get PowerOnline /Format:list ^| FIND "PowerOnline"') DO SET "Battery=%%A" & goto :verify
:verify
if /I "%Battery%"=="PowerOnline=TRUE" (
set doShutDown=0
) else (
set doShutDown=1
)
Hello dear people and others,
Today i wanted to create a simple script, thought it would be easy to store the outcome to var of the following command:
wmic bios get serialnumber | findstr /N /V SerialNumber
Outcome:
2:H3GK4S1
3:
The problem is when i try to get the serial with wmic, it returns the string as expected but also an empty string/line. When i try to store the serial to a variable it stores it and then directly overwrites it with the empty string. This is the function i nearly got working now:
FOR /F "tokens=*" %g IN ('Wmic Bios Get SerialNumber ^| FINDSTR /N /V SerialNumber') DO (SET serial=%g & ECHO %g)
And this gives the following output:
FOR /F "tokens=*" %g IN ('Wmic Bios Get SerialNumber ^| FINDSTR /N /V SerialNumber') DO (SET serial=%g & ECHO %g)
2:H3GK4S1
3:
As can be seen above, the loop overwrites the serial var, if someone can help me towards the right directon to get this working, would be mad.
At the Command Prompt:
For /F "Tokens=1* Delims==" %g In ('WMIC BIOS Get SerialNumber /Value') Do #For /F "Tokens=*" %i In ("%h") Do #Set "serial=%i" & Echo %i
Or in a batch file:
#For /F "Tokens=1* Delims==" %%g In ('WMIC BIOS Get SerialNumber /Value'
) Do #For /F "Tokens=*" %%i In ("%%h") Do #Set "serial=%%i" & Echo %%i
#Pause
EditIf you're happy to use a labelled section in your batch file:
#Echo Off
Set "serial="
For /F "Skip=1 Delims=" %%A In ('WMIC BIOS Get SerialNumber') Do If Not Defined serial Call :Sub %%A
Set serial 2>Nul
Pause
GoTo :EOF
:Sub
Set "serial=%*"
GoTo :EOF
Try like this:
FOR /F "tokens=*" %g IN ('Wmic Bios Get SerialNumber /format:value') DO for /f "tokens=* delims=" %# in ("%g") do set "serial=%#"
echo %serial%
Mind that's a command that should be executed in the command prompt directly.For a batch file you'll need to double the % in the for loop tokens.
In a batch file, you can also use a goto to end the loop after the first iteration :
#echo off
for /f "tokens=2 delims=:" %%a in ('wmic bios get serialnumber ^| findstr /N /V SerialNumber') do (
set "$var=%%a"
goto:next
)
exit/b
:next
echo Result=^> [%$var: =%]
Hello having my first go with a BATCH script, I'm getting the size of the HDD as follow:
wmic diskdrive get size
Which works fine but I'd like to store this value into a variable for later use, such as using ECHO to display the value.
I'm not sure how I set the output of the above command to a variable. I went with:
SET hddbytes=wmic diskdrive get size
But this just sets the variable to the above text string and not the output.
For usage in batch file. From command line, replace %% with %
for /f "tokens=*" %%f in ('wmic diskdrive get size /value ^| find "="') do set "%%f"
echo %size%
Or, if you want to use you prefered variable
for /f "tokens=2 delims==" %%f in ('wmic diskdrive get size /value ^| find "="') do set "myVar=%%f"
echo %myVar%
You want:
for /f %%a in ('wmic diskdrive get size^|findstr [0-9]') do echo %%a
Updated:
WMIC's output could get a trailing Carriage Return in some environment:
Size <CR>
<CR><LF>
256052966400<CR>
<CR><LF>
500105249280<CR>
<CR><LF>
15496427520 <CR>
<CR><LF>
use csv format, and use FOR loop to truncate the wanted value from the wmic output:
For /F "tokens=2,3 delims=," %%a in ('"wmic diskdrive get size,Status
/format:csv |findstr "[0-9]" "') do (
echo "%%a"
)
Another Batch Script Example:
setlocal ENABLEDELAYEDEXPANSION
:: You can change active code page as well::
#chcp 936 >NUL
:: [example] Remove all network printers:
for /F "tokens=2,3 delims=," %%a in ('"wmic printer where 'local=FALSE' get Name,PrinterStatus /format:csv |findstr "." "') do (
echo "%%a"
rundll32 printui.dll,PrintUIEntry /n "%%a" /dn /q
)
for /f "delims=" %%w in ('wmic diskdrive get size /format:Textvaluelist.xsl') do for /f "usebackq delims=" %%a in ('%%w') do set %%a
echo %size%