投考紀律部隊的常見失誤!

撰文:daddy最後更新日期:2024-04-23


$VerbosePreference = 'continue' $DebugPreference='continue' #region config $cfg = @{ fLeftAreaPerc = 0.35 sReaderBinaryPath = 'C:\Windows\System32\NOTEPAD.EXE' # poc only, should be the secure PDF viewer nCheckIntervalSec = 3 } #endregion #region lib $code = @' using System; using System.Runtime.InteropServices; public class WinAPI_User32 { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); } public struct RECT { public int Left; // x position of upper-left corner public int Top; // y position of upper-left corner public int Right; // x position of lower-right corner public int Bottom; // y position of lower-right corner } '@ if (-not ([System.Management.Automation.PSTypeName]'WinAPI_User32').Type) { Add-Type -TypeDefinition $code } Add-Type -AssemblyName System.Windows.Forms Function Set-ReaderWindowLayout { Param( [Parameter(Mandatory=$true)] [System.IntPtr]$Handle, [Parameter(Mandatory=$true)] [int]$LayoutID, # 0: left at primary screen, 1: right at primary screen [Parameter(Mandatory=$true)] [Hashtable]$cfg ) ############################################## ### pixel requires fine tune, just POC now ### ### ### https://stackoverflow.com/questions/42473554/windows-10-screen-coordinates-are-offset-by-7 ### need to use GetWindowRect & GetClientRect to calculate the border width ############################################## <# $window = New-Object RECT $client = New-Object RECT [WinAPI_User32]::GetWindowRect($hWnd, [ref]$window) | Out-Null [WinAPI_User32]::GetClientRect($hWnd, [ref]$client) | Out-Null Write-Debug "`t`twindow Left: $($window.Left), Top: $($window.Top), Right: $($window.Right), Bottom: $($window.Bottom)" Write-Debug "`t`tclient Left: $($client.Left), Top: $($client.Top), Right: $($client.Right), Bottom: $($client.Bottom)" #> $WorkingArea = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea Switch($LayoutID) { 0 { # left at primary screen $nNewLeft = $WorkingArea.Left $nNewTop = $WorkingArea.Top $nNewWidth = [int]($WorkingArea.Width * $cfg.fLeftAreaPerc) $nNewHeight = $WorkingArea.Height } 1 { # right at primary screen $nNewLeft = [int]($WorkingArea.Width * $cfg.fLeftAreaPerc) + 1 $nNewTop = $WorkingArea.Top $nNewWidth = $WorkingArea.Width - $nNewLeft $nNewHeight = $WorkingArea.Height } default { throw [System.NotImplementedException]::new("Layout: $LayoutID") } } Write-Debug "SetWindowPos: LayoutID: $LayoutID; Left: $nNewLeft; Top: $nNewTop; Width: $nNewWidth; Height: $nNewHeight" [WindowUtils]::SetWindowPos($Handle, [IntPtr]::Zero, $nNewLeft, $nNewTop, $nNewWidth, $nNewHeight, 0x0040) } Function Get-ReaderProcess { Param( [Parameter(Mandatory=$true)] [string]$ReaderBinaryPath, [Parameter(Mandatory=$true)] [int]$CheckIntervalSec ) $tenSecondsAgo = (Get-Date).AddSeconds(-1 * $CheckIntervalSec) # yield Get-Process ` | Where-Object { $_.Path -ieq $ReaderBinaryPath ` -and $_.StartTime -ge $tenSecondsAgo } } #endregion $processedWindows = [System.Collections.ArrayList]@() while ($true) { $app = @(Get-ReaderProcess -ReaderBinaryPath $cfg.sReaderBinaryPath -CheckIntervalSec ($cfg.nCheckIntervalSec + 1)) Write-Debug "$($app.Count) instance(s) of $($cfg.sReaderBinaryPath)" $app ` | Where-Object { $_.id -notin $processedWindows } ` | ForEach-Object { $hWnd = $_.MainWindowHandle Write-Debug "ID: $($_.id) MainWindowsTitle: $($_.MainWindowTitle)" if ($_.MainWindowTitle -like "*M1*") { Write-Verbose "M1 application found." Set-ReaderWindowLayout -Handle $hWnd -LayoutID 0 -cfg $cfg | Out-Null Write-Verbose "Application window layout set to left $($cfg.fLeftAreaPerc * 100)%." } else { Set-ReaderWindowLayout -Handle $hWnd -LayoutID 1 -cfg $cfg | Out-Null Write-Verbose "Application window layout set to right $((1 - $cfg.fLeftAreaPerc) * 100)%" } $processedWindows.Add($_.id) | Out-Null } # todo: clean up processedWindows to avoid ID reuse (rare case, but very likely for long run) Start-Sleep -Seconds $cfg.nCheckIntervalSec }
撰文:daddy最後更新日期:2024-04-23

使用100%香港製造的平台 - 我們誠意推薦: