$User32MethodDefinition = @' [DllImport("user32.dll", EntryPoint = "FindWindowEx")] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("User32.dll")] public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam); '@ $User32 = Add-Type -MemberDefinition $User32MethodDefinition -Name 'user32' -Namespace 'Win32' -PassThruZa każdym razem jak uruchomimy skrypt to będziemy musieli stworzyć nowy obiekt $user32 (i będziemy musieli wiedzieć czy obiekt ma wymagane metody). Dlatego potrzebna nam będzie funkcja sprawdzająca metody statyczne na obiekcie
function Test-StaticMembers { param( [ValidateNotNull()] $objectToTest , [string[]] $members) [array]$result = $objectToTest.GetMembers() | ? {$_.IsStatic -eq $true -and $_.IsPublic -eq $true} | ? {$_.IsAbstract -eq $false -and $_.IsConstructor -eq $false} | ? { $members -contains $_.Name} if( $result.Count -eq $members.Count) { return $true} throw "Not all member are in object. Searching for members: $members" }Sprawdzanie obiektu wygląda następująco:
if( ! $User32 -OR !(Test-StaticMembers -objectToTest $User32 -members 'FindWindowEx','SendMessage' ) ) { $User32 = Add-Type -MemberDefinition $User32MethodDefinition -Name 'user32' -Namespace 'Win32' -PassThru }Teraz będziemy mogli stworzyć funkcje do wysyłania outputu tekstu do dowolnej aplikacji:
Function Out-Applciation { Param( [Parameter(ValueFromPipeline = $true)] [string] $text , [switch] $toAll, [switch] $passResult , [string] $appName ) Begin{ $textArray = @() $intPtr = New-Object 'IntPtr' -ArgumentList '0' if($toAll) { $appProcesses = Get-Process -Name $appName -ErrorAction SilentlyContinue } else { $appProcesses =@( Start-Process -FilePath $appName -PassThru ) } #check if process list exist if(! $appProcesses) { Start-Process -FilePath $appName $appProcesses = Get-Process -Name $appName } } Process{ $textArray += $text } End{ $textString = $textArray | out-string $appProcesses | %{ $findWindowExTryCounter = 0 while(!$windowExChild -OR $windowExChild -eq 0) { $windowExChild = $User32::FindWindowEx($_.MainWindowHandle, $intPtr,'Edit', $null ) #if FindWindowEx will not work $findWindowExTryCounter++ if($findWindowExTryCounter -gt 100) { throw "Can not find window $($_.MainWindowHandle) for $appName" } else { Start-Sleep -Milliseconds 100 } } $result = $User32::SendMessage($windowExChild, '0x000C', 0, $textString ) if($passResult) {$result} #if 1 then is has been send } } }Do tego stworzymy pomocna funkcję do wysyłania wyjścia na notepad:
function Out-Notepad { param( [switch] $toAll, [switch] $passResult ) Begin{ $appName = 'notepad' } End{ $input | Out-Applciation -toAll:$toAll -passResult:$passResult -appName $appName } }Dla przykładu zastosowania out-notepad, pomocna nam będzie funkcja numerująca stringi w kolekcji:
function Numerate-String { Param( [Parameter(ValueFromPipeline = $true)] [string] $text, [string] $seperator=':' ) begin{ $count =0 } process{ $result = "$count $seperator"+ [System.Environment]::NewLine + $text $count++ return $result } }
A wywołanie może byglądać następująco:
gc applicationName.log | Numerate-String | Out-Notepad
Brak komentarzy:
Prześlij komentarz