Integrate AutoIt in PowerShell
Scripting languages plays an important role in the field of automation approaches, also and especially in the SAP context. You can find my automation approach here. In a few cases can it be profitable to combine different scripting languages. Each of them has its preferences and specialities to solve problems easily. And that is our benefit, to use the scripting language in that case where it offers us the best opportunities. An automation engineer must not be shy here. With the agile software development it is our task to develop tests agile as well. So we can not spend time to realize all solutions with one language, like a domain-specific language – which are generally accepted.
In the following example I show a way to combine PowerShell with AutoIt. The complete AutoIt script is in the Here-String $Au3Script. The AutoIt script opens the memory mapped file, reads some data, shows it in a message box and writes some data in the memory mapped file. The PowerShell script creates the memory mapped file, writes some data in it, executes the AutoIt script and reads the data from the memory mapped file.
#-Begin----------------------------------------------------------------- $Au3Script = @' ;-Begin----------------------------------------------------------------- ;-Directives---------------------------------------------------------- #NoTrayIcon AutoItSetOption("MustDeclareVars", 1) ;-Includes------------------------------------------------------------ #Include #Include #Include <WinAPISys.au3"> ;-Sub Main------------------------------------------------------------ Func Main() ;-Opens the access the memory mapped file--------------------------- Local $hMapping = _WinAPI_OpenFileMapping("Test") If Not $hMapping Then Return ;-Reads text from memory mapped file-------------------------------- Local $pAddress = _WinAPI_MapViewOfFile($hMapping) Local $tData = DllStructCreate('wchar[2048]', $pAddress) Local $sText = DllStructGetData($tData, 1) Sleep(250) MsgBox(0, "AutoIt", $sText) ;-Writes text to memory mapped file--------------------------------- _WinAPI_ZeroMemory($tData, 2048) DllStructSetData($tData, 1, "AutoIt is cool man") Sleep(250) ;-Closes the access to memory mapped file--------------------------- _WinAPI_UnmapViewOfFile($pAddress) _WinAPI_CloseHandle($hMapping) EndFunc ;-Main---------------------------------------------------------------- Main() ;-End------------------------------------------------------------------- '@ #-Sub Main------------------------------------------------------------ Function Main() { #-Creates memory mapped file---------------------------------------- [System.IO.MemoryMappedFiles.MemoryMappedFile]$hFile = ` [System.IO.MemoryMappedFiles.MemoryMappedFile]::CreateOrOpen("Test", ` 2048, [System.IO.MemoryMappedFiles.MemoryMappedFileAccess]::ReadWrite); #-Creates accessor for direct access-------------------------------- [System.IO.MemoryMappedFiles.MemoryMappedViewAccessor]$Accessor = ` $hFile.CreateViewAccessor(); #-Writes text to memory mapped file--------------------------------- [String]$Text = "Hello World" [Byte[]]$Buffer = [System.Text.ASCIIEncoding]::Unicode.GetBytes($Text); $Accessor.Write(0, $Buffer.Length); $Accessor.WriteArray(0, $Buffer, 0, $Buffer.Length); #-Creates AutoIt script file from Here-String----------------------- $Au3ScriptFile = "C:DummyScript.ps1.au3" $Au3Script | Out-File -FilePath $Au3ScriptFile #-Executes AutoIt script synchronously------------------------------ $Cmd = "C:AutoItAutoIt3.exe" $Par = $Au3ScriptFile Start-Process $Cmd -ArgumentList $Par -Wait #-Deletes AutoIt script file---------------------------------------- Remove-Item $Au3ScriptFile #-Reads text from memory mapped file-------------------------------- $Buffer = New-Object Byte[] 2048; [Void]$Accessor.ReadArray(0, $Buffer, 0, $Buffer.Length); $Text = [System.Text.ASCIIEncoding]::Unicode.GetString($Buffer); $Text = $Text.Trim(0); Write-Host ($Text); #-Deletes accessor-------------------------------------------------- $Accessor.Dispose(); #-Deletes memory mapped file---------------------------------------- $hFile.Dispose(); } #-Main---------------------------------------------------------------- Main #-End-------------------------------------------------------------------
The communication between the different scripting languages is done with memory mapped file. In that case 2048 bytes with 1024 characters. This is an easy way of process communication.
In the next example I get via AutoIt a list of all windows with its handles. The memory mapped file is here an array of bytes with the size of 16384. If you should do the same with PowerShell, you must integrate C# code.
#-Begin----------------------------------------------------------------- $Au3Script = @' ;-Begin----------------------------------------------------------------- ;-Directives---------------------------------------------------------- #NoTrayIcon AutoItSetOption("MustDeclareVars", 1) ;-Includes------------------------------------------------------------ #Include #Include #Include ;-Function strWinList------------------------------------------------- Func strWinList($Title = Null) Local $aList, $i, $sList If $Title = Null Then $aList = WinList() Else $aList = WinList($Title) EndIf For $i = 1 To $aList[0][0] If $aList[$i][0] = "" Then ContinueLoop $sList = $sList & $aList[$i][0] & ";" & $aList[$i][1] & @CrLf Next Return $sList EndFunc ;-Sub Main------------------------------------------------------------ Func Main() ;-Opens the access the memory mapped file--------------------------- Local $hMapping = _WinAPI_OpenFileMapping("WinList") If Not $hMapping Then Return ;-Reads text from memory mapped file-------------------------------- Local $pAddress = _WinAPI_MapViewOfFile($hMapping) Local $tData = DllStructCreate('byte[16384]', $pAddress) Local $sText = BinaryToString(DllStructGetData($tData, 1), 2) If $sText = "" Then Local $sList = strWinList() Else Local $sList = strWinList($sText) EndIf Sleep(250) ;-Writes text to memory mapped file--------------------------------- _WinAPI_ZeroMemory($tData, 16384) DllStructSetData($tData, 1, StringToBinary($sList, 2)) Sleep(250) ;-Closes the access to memory mapped file--------------------------- _WinAPI_UnmapViewOfFile($pAddress) _WinAPI_CloseHandle($hMapping) EndFunc ;-Main---------------------------------------------------------------- Main() ;-End------------------------------------------------------------------- '@ #-Function GetWinList------------------------------------------------- Function GetWinList([String]$Title = "") { [System.IO.MemoryMappedFiles.MemoryMappedFile]$hFile = ` [System.IO.MemoryMappedFiles.MemoryMappedFile]::CreateOrOpen("WinList", ` 16384, [System.IO.MemoryMappedFiles.MemoryMappedFileAccess]::ReadWrite); [System.IO.MemoryMappedFiles.MemoryMappedViewAccessor]$Accessor = ` $hFile.CreateViewAccessor(); [String]$Text = $Title [Byte[]]$Buffer = [System.Text.ASCIIEncoding]::Unicode.GetBytes($Text); $Accessor.Write(0, $Buffer.Length); $Accessor.WriteArray(0, $Buffer, 0, $Buffer.Length); $Au3ScriptFile = "C:DummyWinList.ps1.au3" $Au3Script | Out-File -FilePath $Au3ScriptFile $Cmd = "C:AutoItAutoIt3.exe" $Par = $Au3ScriptFile Start-Process $Cmd -ArgumentList $Par -Wait Remove-Item $Au3ScriptFile $Buffer = New-Object Byte[] 16384; [Void]$Accessor.ReadArray(0, $Buffer, 0, $Buffer.Length); $Text = [System.Text.ASCIIEncoding]::Unicode.GetString($Buffer); $Text = $Text.Trim(0); $Accessor.Dispose(); $hFile.Dispose(); Return $Text } #-Sub Main------------------------------------------------------------ Function Main() { $Text = GetWinList Write-Host $Text } #-Main---------------------------------------------------------------- Main #-End-------------------------------------------------------------------
With AutoIt you use only the command WinList. Only the process communication increases the complexity here.
Enjoy it.
Cheers
Stefan
New NetWeaver Information at SAP.com
Very Helpfull