8

I'm not even sure where to start with my question, I tried a hundred things and googled for hours but didn't find anything useful. (I'm open to every dirty trick.)

Here's my problem:

I have a .hta-file with a listbox that looks like this:

hta file

It lists all sessions/modi of my SAP Gui running.

        Set SapGuiAuto  = GetObject("SAPGUI")
        Set application = SapGuiAuto.GetScriptingEngine
    
        If application.Connections.Count > 0 Then
            Set connection  = application.Children(0)
            
            If connection.Sessions.Count > 0 Then
                Set session = connection.Children(0)
            End If
        End If


        If IsObject(WScript) Then
            WScript.ConnectObject session,     "on"
            WScript.ConnectObject application, "on"
        End If

Set optGroup = Document.createElement("OPTGROUP")
    optGroup.label = "Server"
    
    
    'count all connected servers 
    ConnectionCount = application.Connections.Count
    
    

    
        If ConnectionCount > 0 Then
            Sessionlist.appendChild(optGroup)
            
            Else 
            optGroup.label = "No connection here."
            
            
        End If
        'count all sessions per server
        
        
        If ConnectionCount > 0 Then
            For Each conn in application.Connections
            
                'Text output connections and sessions
                
                SessionCount = conn.Sessions.Count
                whatIsIt  = conn.Description
                ConnectionFeld.innerhtml = ConnectionFeld.innerhtml & " <br> " & SessionCount & " Sessions auf " & whatIsIt
                
                'fill listbox with all connections
                
                Set objOption = nothing
                Set optGroup = Document.createElement("OPTGROUP")
                optGroup.label = conn.Description
                Sessionlist.appendChild(optGroup)
                
                i = 0
                
                    'fill listbox with all sessions
                    For Each sess In conn.Sessions
                    
                        i = i + 1
                        Set objOption = Document.createElement("OPTION")
                        
                            objOption.Text = "Session " & i & ": " & sess.ID
                            objOption.Value = sess.ID
                            SessionList.options.add(objOption)
                        
                    Next
            Next
        
        Else 
        
        Exit Sub
        
        End If

My goal: When I doubleclick on one of the entries in that list, the selected instance of my SAP GUI should come to the foreground/get activated.

Unfortunately my taskmanager only lists one task and that is "SAP Logon". One of my opened windows also has the name "SAP Logon", all others have the same name: "SAP Easy Access".

enter image description here

The only way I can see the IDs of the connection (servername) and the IDs of the session is via extracting them with vbscript. (see above)

Is there any way to do that?

The only workarounds I could think of after trying a thousand solutions are these two:

extremely ugly workaround:

If sessionID = sess.ID Then
    
Set objShell = CreateObject("shell.application")
objShell.MinimizeAll
                        
sess.findById("wnd[0]").maximize

End If

It minimizes all windows an then maximizes the selected SAP GUI window. Unfortunately My HTA-GUI also gets minimized which kinda sucks.

Second idea:

Somehow get to these clickable thingies by shortcut and put that in my script or some other ugly way.

By hand you have to do this:

Click on that little arrow, rightclick on the icon and then leftclick on the name.

info tray symbols

Is there any way to automate this? It's driving me crazy.

Hope someone can help me, it would be GREATLY appreciated.

PS: I'm sitting on a machine with restricted rights and so I may not be able to tackle this with Windows API-ish solutions.

EDIT concerning comments:

It is not possible:

  • to change registry entries
  • create COM objects
  • work with anything else than VBScript
Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Tom K.
  • 1,020
  • 1
  • 12
  • 28
  • What exactly is the reason, why this question was downvoted? O.o – Tom K. Feb 08 '16 at 11:49
  • Probably because you haven't accepted [their answer](http://stackoverflow.com/a/35206506/692942) yet, personally I don't see anything wrong with the question. I've seen far worse. – user692942 Feb 08 '16 at 14:29
  • Why would I accept these... Whatsoever. If you've seen far worse, you've probably seen far better. ;) What could I change to make it more understandable? – Tom K. Feb 08 '16 at 14:40
  • You miss understand me I'm saying there is nothing wrong with the question *(in terms of deserving a down-vote)*. – user692942 Feb 08 '16 at 14:43
  • Yeah, I got that. ;) It's just that I'm sitting in front of that post pushing F5 (figuratively). So I've got enough time on my hand to make this post more clear. – Tom K. Feb 08 '16 at 14:45
  • You could write a COM object (it would need to be registered, that may be an issue) that use UI Automation (https://msdn.microsoft.com/en-us/library/ms788733.aspx in C/C++ or C#) and do smarter things so it's easier to use with VBScript. – Simon Mourier Feb 09 '16 at 07:35
  • @SimonMourier Thanks for the advice! But yeah, unfortunately I'm not allowed to do that. :( – Tom K. Feb 09 '16 at 10:54

4 Answers4

3

Similarly, it also works with the following commands:

session.findById("wnd[0]").iconify
session.findById("wnd[0]").maximize
Pang
  • 9,564
  • 146
  • 81
  • 122
ScriptMan
  • 1,580
  • 1
  • 9
  • 9
  • I tested this again today, works most of the times. Thank you! Dont know why it doesn't work from time to time. – Tom K. Feb 16 '16 at 16:09
2

From Help.

Activates an application window.

object.AppActivate title 

object WshShell object.

title Specifies which application to activate. This can be a string containing the title of the application (as it appears in the title bar) or the application's Process ID.

I don't know what access to info you have about the window. Some COM objects have a HWnd property. This post gets you how to convert a hwnd to a ProcessID to be used above.

How to find the window Title of Active(foreground) window using Window Script Host

This shows how to convert a process command-line to a ProcessID. To see what properties and methods are available use the command-line tool wmic (wmic process get /? and wmic process call /?)

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")

For Each objItem in colItems
    msgbox objItem.ProcessID & " " & objItem.CommandLine
Next
  • Unfortunately I still only get a single process with the following parameters: "ProcessID: 3208 // Name: saplogon.exe // CommandLine: "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe". So there's still no way to find the right window to "AppActivate". :/ – Tom K. Feb 05 '16 at 09:37
  • The process object has a sessionid. –  Feb 05 '16 at 10:07
  • 1
    Maybe I'm not getting this right, but if there's only one process (and this is what I get so far with your code), I only get one SessionID (which is "1"). – Tom K. Feb 05 '16 at 15:41
2

I found it...

The resizeWorkingPane method - for changing the size of a window - also works on windows in the background. If you change the parameters, the window will come to the foreground.

session.findById("wnd[0]").resizeWorkingPane 300,200,false

I have to partially revoke this, because it doesnt work on all windows. I'm still not sure why, but it keeps failing sometimes. Still, it seems to me, that this is the closest you can get.

Tom K.
  • 1,020
  • 1
  • 12
  • 28
0

This is a 100% of the time solution. It's ugly but it works. You can swap out the IQS3 t code for any other one you can confirm the user won't be in and will have access to. Also part of my reasoning for selection of this code is it loads fast.

Set objShell = CreateObject("wscript.shell")
session.findById("wnd[0]/tbar[0]/okcd").text = "/nIQS3"
session.findById("wnd[0]").sendVKey 0
objShell.AppActivate(cstr(session.ActiveWindow.Text))
session.findById("wnd[0]/tbar[0]/btn[3]").press
ABrunette
  • 1
  • 1