Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor
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------------------------------------------------------------
."$PSScriptRoot\COM.ps1"

#-Sub Main------------------------------------------------------------
Function Main() {

[Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic") > $Null
[Reflection.Assembly]::LoadFile("C:\Program Files (x86)\SAP\NWBC50\Interop.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.
Labels in this area