SAP GUI Scripting Recorder with PowerShell
Hello community,
here a SAP GUI Scripting Recorder in PowerShell scripting language.
#-Begin----------------------------------------------------------------- #-Sub Main------------------------------------------------------------ Function Main() { [Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic") > $Null [Reflection.Assembly]::LoadFile($PSScriptRoot + "SAPFEWSELib.dll") > $Null $SapGuiAuto = [Microsoft.VisualBasic.Interaction]::GetObject("SAPGUI") If ($SapGuiAuto -eq $Null) { Break } $Application = $SapGuiAuto.GetType().InvokeMember("GetScriptingEngine", [System.Reflection.Bindingflags]::InvokeMethod, $null, $SapGuiAuto, $null, $null, $null, $null) [SAPFEWSELib.GuiApplication]$Application = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($Application, [SAPFEWSELib.GuiApplicationClass]) If ($Application -eq $Null) { Break } $Connection = $Application.Children.Item(1) [SAPFEWSELib.GuiConnectionClass]$Connection = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($Connection, [SAPFEWSELib.GuiConnectionClass]) If ($Connection -eq $Null) { Break } $Session = $Connection.Children.Item(0) [SAPFEWSELib.GuiSession]$Session = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($Session, [SAPFEWSELib.GuiSessionClass]) If ($Session -eq $Null) { Break } $Session.Record = $True Register-ObjectEvent -InputObject $Session -EventName "Change" -SourceIdentifier "Action" > $Null While ($true) { Write-Host "Waiting for event..." $Event = Wait-Event -SourceIdentifier "Action" -Timeout 10 If ($Event -eq $Null) { Write-Host "No event received for 10 seconds." Break } #$event.SourceArgs Write-Host "ID: " $event.SourceArgs[1].Id Write-Host "Type / Method / Parameter: " $event.SourceArgs[2].SyncRoot Remove-Event -SourceIdentifier "Action" } Unregister-Event -SourceIdentifier "Action" $Session.Record = $False } #-Main---------------------------------------------------------------- Main #-End--------------------------------------------------------------------
As you can see I use the normal SAP GUI Scripting commands to get the application, connection and session. I set the property record of the session object to true and register the change event to record my activities. Now in the while loop, which exits after 10 seconds if no event is fired, I catch the parameters via $event.SourceArgs. Last but not least I unregister the event and set record to false.
Here the result of one activity:
Waiting for event... Name : ses[0] Type : GuiSession TypeAsNumber : 12 ContainerType : True Id : /app/con[1]/ses[0] Parent : System.__ComObject Children : System.__ComObject ActiveWindow : System.__ComObject Info : System.__ComObject Record : True TestToolMode : 0 RecordFile : Busy : False IsActive : True SaveAsUnicode : True ShowDropdownKeys : False PassportTransactionId : 0A64C954920015101318093545917000 PassportPreSystemId : NSP/nsp_NSP_00 PassportSystemId : NSP/nsp_NSP_00 ErrorList : System.__ComObject AccEnhancedTabChain : False AccSymbolReplacement : False IsListBoxActive : False ListBoxTop : 0 ListBoxLeft : 0 ListBoxWidth : 0 ListBoxHeight : 0 ListBoxCurrEntryTop : 0 ListBoxCurrEntryLeft : 0 ListBoxCurrEntryWidth : 0 ListBoxCurrEntryHeight : 0 ListBoxCurrEntry : -1 ProgressPercent : 0 ProgressText : SuppressBackendPopups : Name : shell Type : GuiShell TypeAsNumber : 122 ContainerType : True Id : /shell Parent : Length : 3 LongLength : 3 Rank : 1 SyncRoot : {SP, selectedNode, F00002} IsReadOnly : False IsFixedSize : True IsSynchronized : False Count : 3 Waiting for event... No event received for 10 seconds.
As you can see you get a lot of information. Important is the ID and the SyncRoot. With these information you can build a scripting recorder of your mind.
Here is another (actual) variant with NWBC Interop.SAPFEWSELib.dll:
#-Begin----------------------------------------------------------------- #-Includes------------------------------------------------------------ ."$PSScriptRootCOM.ps1" #-Sub Main------------------------------------------------------------ Function Main() { [Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic") > $Null [Reflection.Assembly]::LoadFile("C:Program Files (x86)SAPNWBC50Interop.SAPFEWSELib.dll") > $Null $SapGuiAuto = Get-Object( , "SAPGUI") If ($SapGuiAuto -isnot [System.__ComObject]) { Break } $Application = Invoke-Method $SapGuiAuto "GetScriptingEngine" [Interop.SAPFEWSELib.GuiApplication]$Application = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($Application, [Interop.SAPFEWSELib.GuiApplicationClass]) If ($Application -isnot [System.__ComObject]) { Break } $Connection = $Application.Children.Item(0) If ($Connection -eq $Null) { Break } Else { [Interop.SAPFEWSELib.GuiConnectionClass]$Connection = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($Connection, [Interop.SAPFEWSELib.GuiConnectionClass]) } $Session = $Connection.Children.Item(0) If ($Session -eq $Null) { Break } Else { [Interop.SAPFEWSELib.GuiSession]$Session = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($Session, [Interop.SAPFEWSELib.GuiSessionClass]) } $Session.Record = $True Register-ObjectEvent -InputObject $Session -EventName "Change" -SourceIdentifier "Action" > $Null While ($true) { Write-Host "Waiting for event..." $Event = Wait-Event -SourceIdentifier "Action" -Timeout 10 If ($Event -eq $Null) { Write-Host "No event received for 10 seconds." Break } [Interop.SAPFEWSELib.GuiSession]$RecSession = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($event.SourceArgs[0], [Interop.SAPFEWSELib.GuiSessionClass]) Write-Host ( $RecSession | Format-List | Out-String ) #Without this line above delivers PowerShell with the command: #Write-Host ( $RecComponent | Select -ExpandProperty "ID" ) #the error: #The data necessary to complete this operation is not yet available. #(Exception from HRESULT: 0x8000000A) [Interop.SAPFEWSELib.GuiComponent]$RecComponent = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($event.SourceArgs[1], [Interop.SAPFEWSELib.GuiComponentClass]) Write-Host ( $RecComponent | Format-List | Out-String ) #Write-Host ( $RecComponent | Select -ExpandProperty "ID" ) #Write-Host "Type / Method / Parameter: " $event.SourceArgs[2] Remove-Event -SourceIdentifier "Action" } Unregister-Event -SourceIdentifier "Action" $Session.Record = $False } #-Main---------------------------------------------------------------- Main #-End--------------------------------------------------------------------
Here the result of one activity:
Waiting for event... Name : ses[0] Type : GuiSession TypeAsNumber : 12 ContainerType : -1 Id : /app/con[0]/ses[0] Parent : System.__ComObject Children : System.__ComObject ActiveWindow : System.__ComObject Info : System.__ComObject Record : -1 TestToolMode : 0 RecordFile : Busy : 0 IsActive : -1 SaveAsUnicode : -1 ShowDropdownKeys : 0 PassportTransactionId : 58266AFB639E8990E10000000A64C9A0 PassportPreSystemId : NSP/nsp_NSP_00 PassportSystemId : NSP/nsp_NSP_00 ErrorList : System.__ComObject AccEnhancedTabChain : 0 AccSymbolReplacement : 0 IsListBoxActive : 0 ListBoxTop : 0 ListBoxLeft : 0 ListBoxWidth : 0 ListBoxHeight : 0 ListBoxCurrEntryTop : 0 ListBoxCurrEntryLeft : 0 ListBoxCurrEntryWidth : 0 ListBoxCurrEntryHeight : 0 ListBoxCurrEntry : -1 ProgressPercent : 0 ProgressText : SuppressBackendPopups : Name : btn[3] Type : GuiButton TypeAsNumber : 40 ContainerType : 0 Id : /app/con[0]/ses[0]/wnd[0]/tbar[0]/btn[3] Parent : System.__ComObject Waiting for event... No event received for 10 seconds.
As you can see a tiny difference in the component object.
Enjoy it.
Cheers
Stefan
New NetWeaver Information at SAP.com
Very Helpfull