屏幕锁定时有没有办法获取窗口的图像?
我使用RoughDraft的Get-Screenshot来捕获窗口截图,但显然它在屏幕锁定时无法正常工作。
在我们的环境中,我们使用Powershell,因此我的脚本如下所示:
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public static class Win32Api
{
public static uint WM_CLOSE = 0x10;
[System.Runtime.InteropServices.DllImportAttribute( "User32.dll", EntryPoint = "GetWindowThreadProcessId" )]
public static extern int GetWindowThreadProcessId ( [System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, out int lpdwProcessId );
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(IntPtr sClassName, String sAppName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
}
"@
....cut....
try {
while ($ProcessActive.Id -ne $null) {
$find_window = [Win32Api]::FindWindow([IntPtr]::Zero, $wname )
$ProcessActive = Get-Process -Id $app.Id -ErrorAction SilentlyContinue
$get_pid = [Win32Api]::GetWindowThreadProcessId( $find_window, [ref] $dbPID );
if ($find_window -ne 0 -And $dbPID -eq $app.Id) {
Write-Host "[ERROR] Warning window found:" $find_window -NoNewline
Write-Host ", and has parent PID:" $dbPID
if (Test-Path warning-$dbPID-scr0.JPEG) {
Write-Host "[STATUS] Old screenshot file exist, cleaning..."
Remove-Item warning-$dbPID-scr0.JPEG
}
Get-ScreenShot -OfWindow -Path warning-$dbPID-scr
if (Test-Path warning-$dbPID-scr0.JPEG) {
Write-Host Saved screenshot as warning-$dbPID-scr0.JPEG
}
else {
Write-Host "[ERROR] Error while saving screenshot!"
}
$zero = [IntPtr]::Zero
$send_close = [Win32Api]::SendMessage( $find_window, [Win32Api]::WM_CLOSE, $zero, $zero )
Write-Host "[ERROR] Exit with code 1 (this is not good)"
exit 1
}
catch {
$ErrorMessage = $_.Exception.Message
Write-Host "We'v got this: $ErrorMessage"
}
答案 0 :(得分:1)
要获取窗口的屏幕截图,应用程序必须调用GetDC / GetDCEx以获取代表窗口屏幕区域的设备上下文。
这总是返回一个代表显示器上窗口位置的DC,并被剪切到显示器上的窗口可见区域。
这意味着,当您绘制到Windows DC时,您将直接绘制到显示设备上,尽管剪裁时不能在窗口可见区域的边界外绘制。
这也意味着,如果你使用这个DC作为源DC来捕获窗口的屏幕截图,那么在显示设备上,“现在”的窗口部分实际上没有可见的部分像素。
如果(并且这是一个非常大的IF),所讨论的窗口实际上支持WM_PRINT消息,您可以使用PrintWindow
API来鼓励窗口将自己绘制到您提供的DC上。这应该使它从头开始绘画,你可能会得到一个很好的Windows内容副本。