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
In the context of a discussion I developed and presented a complete launch sequence of SAP GUI Scripting in VBScript. But for the future it seems better to use PowerShell, for reasons which I have described here. Now the equivalent in PowerShell script language:
#-Begin-----------------------------------------------------------------

#-Includes------------------------------------------------------------
. "$PSScriptRoot\COM.ps1"

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

$OpenNewConnFlag = $false

if (-Not (Get-Process saplogon -ErrorAction silentlycontinue)) {
Start-Process "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe"
do {
Start-Sleep -Milliseconds 250
} until(Get-Process | where {$_.mainWindowTitle -like "SAP Logon 740"})
}
$SapGuiAuto = Get-Object( , "SAPGUI")
$application = Invoke-Method $SapGuiAuto "GetScriptingEngine"
$connection = Get-Property $application "Children" @(0)
if ($connection -eq $Null) {
$OpenNewConnFlag = $true
Invoke-Method $application "OpenConnectionByConnectionString" `
@("/H/10.100.200.300/S/3200", $true) > $Null
$connection = Get-Property $application "Children" @(0)
}
$session = Get-Property $connection "Children" @(0)

if ($OpenNewConnFlag -eq $true) {
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-MANDT")
Set-Property $ID "Text" @("001")
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME")
Set-Property $ID "Text" @("BCUSER")
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE")
Set-Property $ID "Text" @("minisap")
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU")
Set-Property $ID "Text" @("EN")
$ID = Invoke-Method $session "findById" @("wnd[0]")
Invoke-Method $ID "sendVKey" @(0)
}

Free-Object $session
Free-Object $connection
Free-Object $application
Free-Object $SapGuiAuto

}

#-Main----------------------------------------------------------------
Main

#-End-------------------------------------------------------------------

Here now the facelifted COM include, which I introduced here:
#-Begin-----------------------------------------------------------------

#-Load assembly-------------------------------------------------------
[Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic") > $Null
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > $Null

#-Function Create-Object----------------------------------------------
Function Create-Object([String]$objectName) {
try {
New-Object -ComObject $objectName
}
catch {
[Void] [System.Windows.Forms.MessageBox]::Show(
"Can't create object", "Important hint", 0)
}
}

#-Function Get-Object-------------------------------------------------
Function Get-Object([String]$pathName, [String]$class) {
[Microsoft.VisualBasic.Interaction]::GetObject($pathName, $class)
}

#-Sub Free-Object-----------------------------------------------------
Function Free-Object([__ComObject]$object) {
[Void] [System.Runtime.Interopservices.Marshal]::ReleaseComObject($object)
}

#-Function Get-Property-----------------------------------------------
Function Get-Property([__ComObject]$object, [String]$propertyName,
$propertyParameters) {
$objectType = [System.Type]::GetType($object)
$objectType.InvokeMember($propertyName,
[System.Reflection.Bindingflags]::GetProperty,
$null, $object, $propertyParameters)
}

#-Sub Set-Property----------------------------------------------------
Function Set-Property([__ComObject]$object, [String]$propertyName,
$propertyValue) {
$objectType = [System.Type]::GetType($object)
[Void] $objectType.InvokeMember($propertyName,
[System.Reflection.Bindingflags]::SetProperty,
$null, $object, $propertyValue)
}

#-Function Invoke-Method----------------------------------------------
Function Invoke-Method([__ComObject]$object, [String]$methodName,
$methodParameters) {
$objectType = [System.Type]::GetType($object)
$output = $objectType.InvokeMember($methodName,
"InvokeMethod", $NULL, $object, $methodParameters)
if ( $output ) { $output }
}

#-End-------------------------------------------------------------------

Hint: This code is a different perspective from the solution here.

 

And here a further development of the approach above:
#-Begin-----------------------------------------------------------------

If ($PSVersionTable.PSVersion.Major -eq 2) {
$PSScriptRoot = Split-Path $($MyInvocation.InvocationName) -Parent
}

#-Includes------------------------------------------------------------
."$PSScriptRoot\COM.ps1"

#-Function Logon------------------------------------------------------
Function Logon() {

$SecPasswd = Read-Host -Prompt "Passwort" -AsSecureString
$ptrPasswd = [Runtime.InteropServices.Marshal]::SecureStringToBStr($SecPasswd)
$Passwd = [Runtime.InteropServices.Marshal]::PtrToStringBStr($ptrPasswd)

Invoke-Method $application "OpenConnectionByConnectionString" `
@("/H/10.100.200.300/S/3200", $True) > $Null
$connection = Get-Property $application "Children" @(0)
$session = Get-Property $connection "Children" @(0)
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-MANDT")
Set-Property $ID "Text" @("001")
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME")
Set-Property $ID "Text" @("BCUSER")
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE")
Set-Property $ID "Text" @($Passwd)
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU")
Set-Property $ID "Text" @("EN")
$ID = Invoke-Method $session "findById" @("wnd[0]")
Invoke-Method $ID "sendVKey" @(0)

$connection
$session
}

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

$Found = $False

If (-Not (Get-Process saplogon -ErrorAction silentlycontinue)) {
Start-Process "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe"
do {
Start-Sleep -Milliseconds 250
} until(Get-Process | where {$_.mainWindowTitle -like "SAP Logon 740"})
}

$SapGuiAuto = Get-Object( , "SAPGUI")
If ($SapGuiAuto -isnot [__ComObject]) {
Exit
}

$application = Invoke-Method $SapGuiAuto "GetScriptingEngine"
If ($application -isnot [__ComObject]) {
Free-Object $SapGuiAuto
Exit
}

$connections = Get-Property $application "Connections"
If ($connections -isnot [__ComObject]) {
$Ret = Logon
$connection = $Ret[0]
$session = $Ret[1]
} Else {

$connections = Get-Property $application "Connections"

:found
ForEach ($connection In $connections) {
$sessions = Get-Property $connection "Sessions"
ForEach ($session In $sessions) {
If ($session.Busy() -eq 1) {
Continue
}
$sessionInfo = Get-Property $session "Info"
$SID = Get-Property $sessionInfo "SystemName"
$TAC = Get-Property $sessionInfo "Transaction"
If ($SID -eq "NSP" -and $TAC -eq "SESSION_MANAGER") {
$Found = $True
Break found
}
}
}

If ($Found = $False) {
$Ret = Logon
$connection = $Ret[0]
$session = $Ret[1]
}

}

#-------------------------------------------------------------------
#-
#- In the variables $connection and $session are now the required
#- information
#-
#-------------------------------------------------------------------



Free-Object $SapGuiAuto

}

#-Main----------------------------------------------------------------
Main

#-End-------------------------------------------------------------------
4 Comments
Labels in this area