Skip to Content

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:\Dummy\Script.ps1.au3"
    $Au3Script | Out-File -FilePath $Au3ScriptFile

    #-Executes AutoIt script synchronously------------------------------
    $Cmd = "C:\AutoIt\AutoIt3.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 <WinAPI.au3>
  #Include <WinAPIFiles.au3>
  #Include <WinAPISys.au3>

  ;-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:\Dummy\WinList.ps1.au3"
    $Au3Script | Out-File -FilePath $Au3ScriptFile

    $Cmd = "C:\AutoIt\AutoIt3.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.

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply