RA-MICRO "Akte anlegen" Dialog per PowerShell automatisiert ausfüllen
| param( | |
| [字符串]$Kurzbezeichnung,# 索引0:文件缩写 | |
| [字符串]$Langbezeichnung,# 索引 1:长文件指定 | |
| [字符串]$Internbezeichnung,# 索引2:文件内部指定 | |
| [字符串]$Datum,# 索引3:创建日期 | |
| [字符串]$Sachbearbeiter,# 索引4:档案员 | |
| [字符串]$Referat,# 索引5:呈现 | |
| [字符串]$Sachstand,# 索引6:游戏状态 | |
| [字符串]$Auftraggeber,# 索引7:客户数量 | |
| [字符串]$Aktenkennzeichen,# 索引 8:文件标识符 | |
| [字符串]$Gegenstandswert,# 索引9:物品价值 | |
| [弦]$Bemerkung,#index 10:备注 | |
| [字符串]$Aufbewahrungsdauer,#index 11:保留期以年计 | |
| [string]$UnterordnerEAkte,# 索引12:子文件夹E文件 | |
| [字符串]$PruefungGwG,# 索引13:审计AMLA(反诽谤法) | |
| [string]$Exklusivbenutzer,#index 14:独家用户 | |
| [哈希表]$ByIndex = @{}, # 保留:按索引直接显示字段 | |
| [字符串]$MaskTitle = “创建文件” | |
| ) | |
| 如果 (-not ('Win32Native' -as [type])) { | |
| Add-Type -TypeDefinition @' | |
| 使用系统; | |
| 使用System.Text; | |
| 使用 System.Runtime.InteropServices; | |
| 公共静态类 Win32Native { | |
| EnumChildWindows 的回调类型 | |
| 公共代理 bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); | |
| 按职业和/或标题搜索窗口 | |
| [DllImport(“user32.dll”, CharSet=CharSet.Unicode)] | |
| public static extern IntPtr FindWindowEx(IntPtr 父,IntPtr childAfter,字符串类名,字符串 windowTitle); | |
| 递归地列出窗口的所有子窗口 | |
| [DllImport(“user32.dll”)] | |
| [返回:MarshalAs(UnmanagedType.Bool)] | |
| public static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); | |
| 读取窗口类(例如“编辑”) | |
| [DllImport(“user32.dll”, CharSet=CharSet.Unicode)] | |
| public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); | |
| 发送窗口消息:WM_SETTEXT(0x000C)、WM_GETTEXT(0x000D)、WM_GETTEXTLENGTH(0x000E) | |
| [DllImport(“user32.dll”, CharSet=CharSet.Unicode, SetLastError=true)] | |
| 公共静态外部 IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, StringBuilder lParam); | |
| 读取窗口屏幕位置 | |
| [DllImport(“user32.dll”)] | |
| [返回:MarshalAs(UnmanagedType.Bool)] | |
| public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); | |
| 检查可见性(筛选隐藏的VB6控件) | |
| [DllImport(“user32.dll”)] | |
| [返回:MarshalAs(UnmanagedType.Bool)] | |
| 公共静态外部布尔 IsWindowVisible(IntPtr hWnd); | |
| GetWindowRect 的结构 | |
| [StructLayout(LayoutKind.Sequential)] | |
| public struct RECT { public int 左、上、右、下; } | |
| } | |
| '@ | |
| } | |
| # [字符串]参数的 real NULL;$null 会被 PowerShell 转换为“” | |
| $nullStr = [System.Management.Automation.Language.NullString]::Value | |
| # 在所有可见的顶层窗口中按标题搜索遮罩窗口 | |
| $mask = [IntPtr]::零 | |
| $cur = [IntPtr]::零 | |
| 虽然 ($true) { | |
| $cur = [Win32Native]::FindWindowEx([IntPtr]::Zero, $cur, $nullStr, $nullStr) # 下一个顶层窗口 | |
| 如果 ($cur -eq [IntPtr]::Zero) { 断开 } # 窗口列表结束 | |
| 如果 (-not [Win32Native]::IsWindowVisible($cur)) { 继续 } # 跳过 invisible | |
| $len = [Win32Native]::SendMessage($cur, 0x000E, [IntPtr]::Zero, $null)。ToInt32() # 读取轨道长度 | |
| 如果 ($len -lt 1) { 继续 } # 跳过无标题 | |
| $title = [System.Text.StringBuilder]::new($len + 1) | |
| [Win32Native]::SendMessage($cur, 0x000D, [IntPtr]($len + 1), $title) |出空 # 阅读标题 | |
| 如果 ($title.ToString() -类似“*$MaskTitle*”) { $mask = $cur; 断开 } # Treffer | |
| } | |
| 如果 ($mask -eq [IntPtr]::Zero) { throw “Mask '*$MaskTitle*' not found.” } | |
| # 收集面具所有可见的编辑字段 | |
| $found = [System.Collections.Generic.List[IntPtr]]::new() | |
| $callback = [Win32Native+EnumWindowsProc]{ param($h, $l) | |
| $cls = [System.Text.StringBuilder]::new(256) | |
| [Win32Native]::GetClassName($h, $cls, $cls.容量) |Out-null | |
| 如果 ($cls.ToString() -eq 'Edit' -和 [Win32Native]::IsWindowVisible($h)) { $found.Add($h) } | |
| 返回$true # 继续枚举 | |
| } | |
| [Win32Native]::EnumChildWindows($mask, $callback, [IntPtr]::Zero) |出空 | |
| # 按掩码顺序排序字段(索引 0 = 顶字段) | |
| $edits = @($found |每个对象 { | |
| $r = [Win32Native+RECT]::new() | |
| [Win32Native]::GetWindowRect($_, [ref]$r) |出空 | |
| [pscustomobject]@{ Hwnd = $_;Y = $r.Top;X = $r.Left } | |
| } |排序对象Y, X) | |
| # 将命名参数映射到字段索引 | |
| $map = [有序]@{ | |
| 短名 = 0;长名 = 1;内部名 = 2;日期 = 3 | |
| 职员 = 4;单位 = 5;状态 = 6;客户 = 7 | |
| 文件标识符 = 8;对象值 = 9;备注 = 10;保留期 = 11 | |
| 子文件夹EAkte = 12;PrüfGwG = 13;独占用户 = 14 | |
| } | |
| foreach($key in $map.钥匙) { | |
| 如果 ($PSBoundParameters.ContainsKey($key)) { $ByIndex[$map[$key]] = $PSBoundParameters[$key] } | |
| } | |
| # 仅显示场总览,不包含填充参数 | |
| 如果 ($ByIndex.计数 -eq 0) { | |
| $i = 0 | |
| $edits |每个对象 { | |
| $len = [Win32Native]::SendMessage($_.Hwnd, 0x000E, [IntPtr]::Zero, $null)。ToInt32() | |
| $txt = [System.Text.StringBuilder]::new($len + 1) | |
| [Win32Native]::SendMessage($_.hwnd, 0x000D, [IntPtr]($len + 1), $txt) |Out-null | |
| [pscustomobject]@{ 索引 = $i++;hwnd = '0x{0:X}' -f $_。hwnd.ToInt64();Inhalt = $txt。ToString() } | |
| } | |
| 返回 # 输出概览,不要更改任何内容 | |
| } | |
| # 按WM_SETTEXT填充字段并回读以便核对 | |
| foreach($entry 在 $ByIndex.GetEnumerator()) { # 循环所有待填充字段;每个条目有键(字段索引)和值(文本) | |
| $i = [整数]$entry。键 # 哈希表键类型为“对象”——显式转换为整数 | |
| 如果 ($i -ge $edits.计数) { # 合理性检查:索引不得超过或超过所找到字段的数量 | |
| 写警告“索引$i不存在 ($($edits.计数)字段)。”# 用警告代替中止,这样其他字段仍然被填满 | |
| 继续 # 跳过本条目,继续阅读下一篇 | |
| } | |
| $hwnd = $edits[$i]。Hwnd # 从按掩罩顺序排序的列表中获取目标字段的窗口句柄(HWND) | |
| #WM_SETTEXT(0x000C):消息告诉控件替换其文本。 | |
| # wParam 不对 WM_SETTEXT 进行评估,因此为 0。 | |
| # lParam 是新文本;StringBuilder 被 P/Invoke 层用作 | |
| # 指向 Unicode 字符串(LPWStr)的指针,Windows 复制内容 | |
| # 跨流程进入目标流程。 | |
| # 返回值(IntPtr)在这里无关紧要,且被丢弃为零, | |
| # 这样它就不会成为控制台输出中不需要的线条。 | |
| [Win32Native]::SendMessage($hwnd, 0x000C, [IntPtr]::Zero, [System.Text.StringBuilder]::new([string]$entry.值)) |出空 | |
| # 回读:核实现场实际内容(验证而非盲目信任) | |
| $len = [Win32Native]::SendMessage($hwnd, 0x000E, [IntPtr]::Zero, $null)。ToInt32() # WM_GETTEXTLENGTH (0x000E):询问当前文本长度(字符数) | |
| $readback = [System.Text.StringBuilder]::new($len + 1) # 创建读取缓冲区;+1 因为WM_GETTEXT附加空终止 | |
| [Win32Native]::SendMessage($hwnd, 0x000D, [IntPtr]($len + 1), $readback) |out-null # WM_GETTEXT (0x000D): wParam = 缓冲区大小,lParam = 缓冲区;Windows 用字段文本填充 | |
| # 输出结果行作为对象:字段索引、HWND 十六进制和读取内容。 | |
| # 由于对象既未被分配到变量,也未被重定向,它出现在控制台中。 | |
| # 如果“内容”与目标值不匹配,例如,写入会被UIPI阻挡。 | |
| [pscustomobject]@{ 索引 = $i;hwnd = '0x{0:X}' -f $hwnd。ToInt64();Inhalt = $readback。ToString() } | |
| } |
评论
?
参与讨论