Ctrl K
ComunidadGuías…

scripts/capture_store_pages.ps1

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Capture Clips Kitty's people-free pages for the Microsoft Store listing.
#
#     powershell -ExecutionPolicy Bypass -File scripts\capture_store_pages.ps1
#
# ONLY visits Models and Settings. Every other page shows the library: clip
# thumbnails on Clip Editor and Creators, and video titles and channel names on
# Dashboard and Queue. None of that belongs in a public listing - the footage
# is someone else's, and neither their face nor their channel name is ours to
# advertise with.
#
# Pass -All to include Dashboard and Queue, for when there is finally footage
# that can be shown.
#
# Uses PrintWindow rather than a screen grab. A screen grab copies whatever
# pixels are at the window's coordinates, so if the app loses focus for even a
# moment the image fills with the desktop behind it - file paths, other
# applications, whatever happens to be open. PrintWindow asks the window to
# draw itself into a bitmap instead, so nothing else can appear in the frame.
# PW_RENDERFULLCONTENT (0x2) is the flag that makes it work for the
# hardware-composited surfaces Chromium uses.
#
# Output: docs/store-screenshots/ (gitignored). Check every image before
# uploading anyway.

param([switch]$All)

Add-Type -AssemblyName System.Drawing
# -ReferencedAssemblies: the inline C# below uses System.Drawing.Bitmap, and
# loading the assembly into PowerShell does not put it on the compiler's path.
Add-Type -ReferencedAssemblies System.Drawing -TypeDefinition @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;
public class Shot {
  [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h);
  [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr h, int c);
  [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr h, out RECT r);
  [DllImport("user32.dll")] public static extern bool SetCursorPos(int x, int y);
  [DllImport("user32.dll")] public static extern void mouse_event(uint f, uint x, uint y, uint d, int e);
  [DllImport("user32.dll")] public static extern bool PrintWindow(IntPtr h, IntPtr dc, uint flags);
  [StructLayout(LayoutKind.Sequential)] public struct RECT { public int L, T, R, B; }

  public static Bitmap Grab(IntPtr h) {
    RECT r; GetWindowRect(h, out r);
    Bitmap bmp = new Bitmap(r.R - r.L, r.B - r.T);
    using (Graphics g = Graphics.FromImage(bmp)) {
      IntPtr dc = g.GetHdc();
      PrintWindow(h, dc, 0x2);   // PW_RENDERFULLCONTENT
      g.ReleaseHdc(dc);
    }
    return bmp;
  }
}
"@
$DOWN = 0x0002; $UP = 0x0004

# Sidebar offsets from the window's top-left, on a 1440x900 window. The
# sidebar is a fixed width, so these hold as the window grows.
$pages = @(
  @{ n = "3-models";   y = 325 },
  @{ n = "4-settings"; y = 373 }
)
if ($All) {
  $pages = @(
    @{ n = "1-dashboard"; y = 133 },
    @{ n = "2-queue";     y = 181 }
  ) + $pages
}
$sidebarX = 110

$proc = Get-Process -Name "Clips Kitty" -ErrorAction SilentlyContinue |
        Where-Object { $_.MainWindowHandle -ne 0 -and $_.MainWindowTitle } |
        Select-Object -First 1
if (-not $proc) { Write-Output "Clips Kitty is not running."; exit 1 }
$h = $proc.MainWindowHandle

$outDir = Join-Path $PSScriptRoot "..\docs\store-screenshots"
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
Get-ChildItem $outDir -Filter *.png -ErrorAction SilentlyContinue | Remove-Item -Force

[void][Shot]::ShowWindow($h, 9)
[void][Shot]::SetForegroundWindow($h)
Start-Sleep -Milliseconds 900

$r = New-Object Shot+RECT
[void][Shot]::GetWindowRect($h, [ref]$r)
Write-Output "window $($r.R - $r.L)x$($r.B - $r.T)"
if (($r.R - $r.L) -lt 1366) { Write-Output "NOTE: under the Store 1366px minimum - maximise and re-run" }

foreach ($p in $pages) {
    # Re-assert focus before every click; a click on an unfocused window is
    # consumed activating it and never reaches the button.
    [void][Shot]::SetForegroundWindow($h)
    Start-Sleep -Milliseconds 250
    [void][Shot]::SetCursorPos($r.L + $sidebarX, $r.T + $p.y)
    Start-Sleep -Milliseconds 200
    [Shot]::mouse_event($DOWN, 0, 0, 0, 0)
    [Shot]::mouse_event($UP, 0, 0, 0, 0)
    Start-Sleep -Milliseconds 2000     # render, plus any fetch the page makes

    $bmp = [Shot]::Grab($h)
    $path = Join-Path $outDir "$($p.n).png"
    $bmp.Save($path, [System.Drawing.Imaging.ImageFormat]::Png)
    $bmp.Dispose()
    Write-Output "  $($p.n).png"
}

Write-Output ""
Write-Output "Captured to docs\store-screenshots\."
if (-not $All) {
  Write-Output "Only Models and Settings: the other pages show titles, channel"
  Write-Output "names or thumbnails. Pass -All if that is wanted."
}