投考紀律部隊的常見失誤!
投考政府工攻略
.
撰文: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