The captured screenshot is automatically saved as JPEG file. The file name contains a time stamp and is based on template "captcon_yyyyMMdd_HHmmss.ssssss.jpg". Microseconds are used to create sufficiently unique file names.
Optionally, the destination folder for the screenshot can be passed as argument.
Steffen
Code: Select all
@echo off &setlocal
call :init_captcon
echo This is a test.
2>nul md "screenshots"
%captcon% 0 "screenshots"
pause
exit /b
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init_captcon
setlocal DisableDelayedExpansion
:: prefer PowerShell Core if installed
for %%i in ("pwsh.exe") do if "%%~$PATH:i"=="" (set "ps=powershell") else set "ps=pwsh"
:: - BRIEF -
:: Take a screenshot of the visible part of a window. Automatically save it as JPEG file.
:: The format of the file name will be "captcon_yyyyMMdd_HHmmss.ssssss.jpg".
:: NOTE: The window to be captured must be the foreground window. Otherwise the macro will fail.
:: - SYNTAX -
:: %captcon% pid ["path"]
:: pid ID of a process whose main window is to be captured
:: Pass 0 to take a screenshot of the current console window
:: path (optional) Folder where the screenshot is saved. If not specified, the current workdir will be used.
:: - EXAMPLES -
:: Take a screenshot and save it in the current workdir:
:: %captcon% 0
:: Take a screenshot and save it on the user's desktop:
:: %captcon% 0 "%userprofile%\Desktop"
set captcon=for %%# in (1 2) do if %%#==2 (^
%=% set "arg=^^!arg:`=``^^!"^&set "arg=^^!arg:{=`{^^!"^&^
%=% for /f "tokens=1*" %%. in ("^^!arg:}=`}^^!") do endlocal^&^
%=% %ps%.exe -nop -ep Bypass -c ^"^
%===% Add-Type -an System.Windows.Forms; Add-Type -an System.Drawing;^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"dwmapi.dll\")]^
%=======% public static extern void DwmGetWindowAttribute(IntPtr hwnd, int attribId, int[] attribVal, int attribLen);^
%=====% [DllImport(\"kernel32.dll\")]^
%=======% public static extern IntPtr GetConsoleWindow();^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern IntPtr GetForegroundWindow();^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void GetMonitorInfoW(IntPtr hMon, int[] monInf);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern IntPtr MonitorFromWindow(IntPtr hwnd, int flags);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetProcessDPIAware();^
%=====% [DllImport(\"shcore.dll\")]^
%=======% public static extern void SetProcessDpiAwareness(int value);^
%===% ';^
%===% $PROCESS_PER_MONITOR_DPI_AWARE=2;^
%===% try {$w::SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)} catch {$w::SetProcessDPIAware()}^
%===% $wpid=0;^
%===% if (-not [Int32]::TryParse('%%~.', [ref]$wpid)) {exit 1}^
%===% if ($wpid -gt 0) {^
%=====% $hwnd=(gps -id $wpid -ea SilentlyContinue).MainWindowHandle;^
%===% } else {^
%=====% $hwnd=$w::GetConsoleWindow();^
%===% }^
%===% if ($hwnd -ne $w::GetForegroundWindow()) {exit 1}^
%=== The $rect array is a replacement for the RECT structure. The elements at index =% ^
%=== 0, 1, 2, and 3 represent left, top, right, and bottom boundaries of the window. =% ^
%===% $rect=[int[]]::new(4);^
%===% $DWMWA_EXTENDED_FRAME_BOUNDS=9;^
%===% $w::DwmGetWindowAttribute($hwnd, $DWMWA_EXTENDED_FRAME_BOUNDS, $rect, 16);^
%=== The $moninf array is a replacement for the MONITORINFO structure. The elements at index =% ^
%=== 5, 6, 7, and 8 represent left, top, right, and bottom boundaries of the monitor's work space. =% ^
%===% $moninf=[int[]]::new(10);^
%===% $moninf[0]=40;^
%===% $MONITOR_DEFAULTTONEAREST=2;^
%===% $w::GetMonitorInfoW($w::MonitorFromWindow($hwnd, $MONITOR_DEFAULTTONEAREST), $moninf);^
%===% $rect=[Math]::Max($rect[0] + 2, $moninf[5]),^
%=========% [Math]::Max($rect[1], $moninf[6]),^
%=========% [Math]::Min($rect[2] - 2, $moninf[7]),^
%=========% [Math]::Min($rect[3] - 2, $moninf[8]);^
%===% $width=$rect[2] - $rect[0];^
%===% $height=$rect[3] - $rect[1];^
%===% $bm=New-Object Drawing.Bitmap($width, $height);^
%===% [Drawing.Graphics]::FromImage($bm).CopyFromScreen($rect[0], $rect[1], 0, 0, \"$width,$height\");^
%===% $name=Join-Path $(if(\"%%~/\") {\"%%~/\".TrimEnd()} else {'.'})^
%===================% $('captcon_' + (Get-Date -f yyyyMMdd_HHmmss.ffffff) + '.jpg');^
%===% $codecInf=[Drawing.Imaging.ImageCodecInfo]::GetImageEncoders()^^^^^^^|?{$_.FormatDescription -eq 'JPEG'};^
%===% $encParams=New-Object Drawing.Imaging.EncoderParameters(1);^
%===% $encParams.Param[0]=New-Object Drawing.Imaging.EncoderParameter([Drawing.Imaging.Encoder]::Quality, 90);^
%===% $bm.Save($name, $codecInf, $encParams);^
%===% $encParams.Dispose();^
%===% $bm.Dispose();^
%=% ^") else setlocal EnableDelayedExpansion^&set arg=
endlocal &set "captcon=%captcon%"
if !!# neq # set "captcon=%captcon:^^!=!%"
exit /b
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
viewtopic.php?f=3&t=9811
In case of the Windows Terminal use the %TermPid% macro. Refer to:
viewtopic.php?f=3&t=10576