Skip to main content

How to Get the Current DPI Scaling Setting in Batch Script

DPI (Dots Per Inch) scaling determines how large text, icons, and UI elements appear on the screen. On high-resolution displays (4K, QHD), Windows automatically increases the DPI scaling percentage so that everything remains readable. While this is great for daily use, it can cause issues for Batch scripts that launch legacy applications, screen capture tools, or automated GUI testing frameworks that assume a 100% scaling baseline.

In this guide, we will explore how to retrieve the current DPI scaling percentage using Batch Script by querying the Windows Registry.

Understanding DPI Scaling in Windows

Windows represents DPI scaling as a logarithmic DPI value in the registry, not as a direct percentage. The mapping between the stored DPI value and the user-facing percentage is:

Registry DPI ValueDisplay ScalingCommon Name
96100%Standard
120125%Medium
144150%Larger
168175%
192200%Extra Large
240250%
288300%

The formula is: Scaling % = (DPI Value / 96) × 100

Method 1: Reading from the Registry

The current user's DPI setting is stored at: HKCU\Control Panel\Desktop Value Name: LogPixels Type: REG_DWORD

However, on modern Windows 10/11 systems with per-monitor DPI awareness, the primary scaling factor may also be found at: HKCU\Control Panel\Desktop\WindowMetrics Value Name: AppliedDPI

@echo off
setlocal enabledelayedexpansion

echo Reading DPI Scaling Setting...
echo ==============================

:: Try AppliedDPI first (Windows 10/11 preferred)
set "dpi="
for /f "tokens=2*" %%A in ('reg query "HKCU\Control Panel\Desktop\WindowMetrics" /v AppliedDPI 2^>nul ^| findstr /i "REG_DWORD"') do set "dpi=%%B"

:: Fallback to LogPixels if AppliedDPI not found
if not defined dpi (
for /f "tokens=2*" %%A in ('reg query "HKCU\Control Panel\Desktop" /v LogPixels 2^>nul ^| findstr /i "REG_DWORD"') do set "dpi=%%B"
)

if not defined dpi (
echo [INFO] No DPI override found. System is likely at default 100%% ^(96 DPI^).
set "dpi=0x60"
)

:: Convert hex to decimal using set /a (handles 0x prefix natively)
set /a "dpi_dec=!dpi!"

:: Calculate the scaling percentage
set /a "scale_pct=(!dpi_dec! * 100) / 96"

echo Raw DPI Value: !dpi! ^(!dpi_dec! decimal^)
echo Scaling Percentage: !scale_pct!%%

pause

Why We Check Two Locations

  • AppliedDPI: This key is written by Windows 10/11 when the user changes the scaling slider in Settings > Display. It reflects the actively applied DPI for the primary display.
  • LogPixels: This is the legacy key used by older Windows versions and some applications. On a fresh Windows 10 install at 100%, this key may not exist at all.
info

Both AppliedDPI and LogPixels are REG_DWORD values stored in hexadecimal format (e.g., 0x60 for 96, 0x78 for 120, 0x90 for 144). The set /a command in Batch natively handles the 0x prefix, converting hexadecimal to decimal automatically. No manual conversion step is needed.

Method 2: Using PowerShell for System DPI

The registry approach reads the primary display's setting. For a programmatic query of the system-level DPI via the Windows API, we can use PowerShell to call GetDeviceCaps.

@echo off
setlocal enabledelayedexpansion

echo Retrieving System DPI via Windows API...
echo =========================================
echo.

set "dpi_x="
set "dpi_y="
set "scale="

:: Write the PowerShell script to a temp file to avoid cmd escaping issues
set "ps_script=%TEMP%\get_dpi_%RANDOM%.ps1"

> "!ps_script!" (
echo Add-Type -TypeDefinition @'
echo using System;
echo using System.Runtime.InteropServices;
echo public class DPIHelper {
echo [DllImport^("user32.dll"^)]
echo public static extern IntPtr GetDC^(IntPtr hwnd^);
echo [DllImport^("gdi32.dll"^)]
echo public static extern int GetDeviceCaps^(IntPtr hdc, int nIndex^);
echo [DllImport^("user32.dll"^)]
echo public static extern int ReleaseDC^(IntPtr hwnd, IntPtr hdc^);
echo }
echo '@
echo $hdc = [DPIHelper]::GetDC^([IntPtr]::Zero^)
echo $dpiX = [DPIHelper]::GetDeviceCaps^($hdc, 88^)
echo $dpiY = [DPIHelper]::GetDeviceCaps^($hdc, 90^)
echo [void][DPIHelper]::ReleaseDC^([IntPtr]::Zero, $hdc^)
echo $scale = [math]::Round^(^($dpiX / 96^) * 100^)
echo Write-Output "DpiX=$dpiX"
echo Write-Output "DpiY=$dpiY"
echo Write-Output "Scale=$scale"
)

for /f "tokens=1* delims==" %%A in ('powershell -NoProfile -ExecutionPolicy Bypass -File "!ps_script!" 2^>nul') do (
if "%%A"=="DpiX" set "dpi_x=%%B"
if "%%A"=="DpiY" set "dpi_y=%%B"
if "%%A"=="Scale" set "scale=%%B"
)

del "!ps_script!" 2>nul

if not defined dpi_x (
echo [ERROR] Could not retrieve DPI information via Windows API.
pause
exit /b 1
)

echo Primary Display DPI: !dpi_x! x !dpi_y!
echo Scaling Percentage: !scale!%%

pause

Understanding GetDeviceCaps

  • Index 88 (LOGPIXELSX): Returns the horizontal DPI of the screen.
  • Index 90 (LOGPIXELSY): Returns the vertical DPI of the screen.

On standard displays, both values are identical (e.g., 96×96 at 100%, 144×144 at 150%).

warning

The GetDeviceCaps function with GetDC(IntPtr.Zero) returns the system DPI, which is the DPI of the primary display. In multi-monitor setups with per-monitor DPI scaling, secondary monitors may use different scaling values. Querying per-monitor DPI requires the GetDpiForMonitor API (available on Windows 8.1+), which involves monitor enumeration and is significantly more complex.

Method 3: Quick One-Liner Check

If you just need a fast check for conditional logic in a deployment script:

@echo off
setlocal

:: Quick DPI check: try AppliedDPI, fallback to LogPixels, default to 96
set "dpi=96"
for /f "tokens=2*" %%A in ('reg query "HKCU\Control Panel\Desktop\WindowMetrics" /v AppliedDPI 2^>nul ^| findstr /i "REG_DWORD"') do set /a "dpi=%%B"
if %dpi% equ 96 (
for /f "tokens=2*" %%A in ('reg query "HKCU\Control Panel\Desktop" /v LogPixels 2^>nul ^| findstr /i "REG_DWORD"') do set /a "dpi=%%B"
)

set /a "scale=(%dpi% * 100) / 96"

if %scale% gtr 100 (
echo [WARNING] Display scaling is at %scale%%%. Some legacy applications may not render correctly.
) else (
echo [OK] Display scaling is at standard 100%%.
)

pause

Practical Use Case: Adjusting Application Launch Parameters

Some legacy applications do not handle high-DPI displays properly and need to be launched with DPI compatibility flags.

@echo off
setlocal

set "app_path=C:\LegacyApp\app.exe"

:: Check scaling
set "dpi=96"
for /f "tokens=2*" %%A in ('reg query "HKCU\Control Panel\Desktop\WindowMetrics" /v AppliedDPI 2^>nul ^| findstr /i "REG_DWORD"') do set /a "dpi=%%A"
if %dpi% equ 96 (
for /f "tokens=2*" %%A in ('reg query "HKCU\Control Panel\Desktop" /v LogPixels 2^>nul ^| findstr /i "REG_DWORD"') do set /a "dpi=%%B"
)
set /a "scale=(%dpi% * 100) / 96"

if %scale% gtr 100 (
echo High-DPI detected ^(%scale%%%^). Setting compatibility mode...

:: Set the application to use "System (Enhanced)" DPI awareness
set "compat_key=HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
REG ADD "%compat_key%" /v "%app_path%" /t REG_SZ /d "~ HIGHDPIAWARE" /f >nul

echo [OK] DPI compatibility override applied for %scale%%% scaling.
)

if not exist "%app_path%" (
echo [ERROR] Application not found: %app_path%
pause
exit /b 1
)

echo Launching application...
start "" "%app_path%"
tip

The ~ HIGHDPIAWARE compatibility flag tells Windows to treat the application as DPI-aware, preventing automatic bitmap stretching. Other available flags include ~ DPIUNAWARE (force the app to run at 96 DPI with system-level scaling) and ~ GDIDPISCALING DPIUNAWARE (enable GDI-based DPI scaling for improved rendering quality). The ~ prefix applies the setting for all users; omit it to apply only when run with "Run as Administrator."

Common Mistakes

The Wrong Way: Assuming 96 DPI on Modern Hardware

:: WRONG - Hardcoding 100% scaling assumption
echo Setting window size to 1920x1080 for full HD...
danger

On a 4K display at 200% scaling, the effective desktop resolution is 1920×1080 logical pixels, but the physical resolution is 3840×2160. Applications that ignore DPI scaling will render at half the expected size or display blurry text. Always check the current scaling before making assumptions about screen coordinates or window sizes.

The Wrong Way: Reading the Wrong Registry Key

:: WRONG - DpiScalingVer is an internal version flag, not the DPI value
reg query "HKCU\Control Panel\Desktop" /v DpiScalingVer

This key tracks the DPI scaling feature version, not the actual DPI setting. Always use AppliedDPI or LogPixels.

The Wrong Way: Parsing Registry Values by Value Name Instead of Type

:: WRONG - findstr /i "AppliedDPI" can match path lines or headers
for /f "tokens=3" %%A in ('reg query "HKCU\...\WindowMetrics" /v AppliedDPI 2^>nul ^| findstr /i "AppliedDPI"') do set "dpi=%%A"
warning

Filtering reg query output by value name (findstr /i "AppliedDPI") can match registry path lines or other output that happens to contain the string. Additionally, tokens=3 is fragile when the output column alignment varies. Use findstr /i "REG_DWORD" to match only the data line, and tokens=2* with %%B to reliably capture the value regardless of column spacing.

Best Practices

  1. Check AppliedDPI first: On Windows 10/11, this is the most accurate and up-to-date value.
  2. Fall back to LogPixels: For compatibility with Windows 7/8 or edge cases where AppliedDPI does not exist.
  3. Default to 96: If neither key exists, assume 96 DPI (100% scaling), which is the Windows default.
  4. Use the formula: Always calculate the percentage as (DPI / 96) * 100 rather than maintaining a hardcoded lookup table, since Windows supports arbitrary scaling values (e.g., 125%, 150%, 175%, 225%).
  5. Use tokens=2* with findstr /i "REG_DWORD": This parsing pattern reliably extracts DWORD values from reg query output regardless of column spacing or value name content.
  6. Use set /a for hex conversion: The set /a command natively handles 0x-prefixed hexadecimal values, converting them to decimal automatically without needing a manual conversion step.

Conclusion

Retrieving the current DPI scaling setting in Batch Script boils down to reading the AppliedDPI or LogPixels registry value and applying a simple formula to convert it into a user-friendly percentage. This information is essential for scripts that launch legacy applications, configure display-dependent settings, or perform pre-deployment checks on high-resolution displays. By detecting non-standard scaling early, your automation scripts can apply appropriate compatibility fixes before users encounter blurry or incorrectly sized interfaces.