0

I am using SAP GUI scripts to automate SAP. These VB scripts are called using the below command.

subprocess.call("cmd /c  .\\VBScripts\\Login.vbs " + '"' + username + '" ' + '"' + password + '"')

But, when a script is invoked when the server window is not launched, the script stops with a pop up. Therefore, I need to check whether there is a connection established to a specific SAP server using python.

Decided to check whether the SAP task (highlighted in the image) is listed in the process list. But, I am unable to list those sub process using python.

Appreciate, if some one can help with above. Or else, suggest a better way to handle above scenario.

enter image description here

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
udani
  • 1,243
  • 2
  • 11
  • 33
  • If you right-click the `SAP` sub-proccess, and click `Go to Details` (or something like that), is there a way to separate the session from the other processes? – Hampus Larsson Oct 21 '19 at 09:56
  • No, it doesn't give such option. Only [Switch to, Bring to front, minimize, maximize, End Task] options. – udani Oct 21 '19 at 10:01

1 Answers1

0

To solve the problem you highlited (list all processes with a certain string in the command line launching them), I use wmic with PID and CommandLine arguments, then filter for the desired command line string and grab it's PID. Below I'm attaching a snippet that does the finding. Also a function to kill them.

def get_running_processes(targ, name):
    pids = []
    if targ == 'win':
        cmd = "WMIC PROCESS get ProcessId,CommandLine"
    else:
        cmd = "ps a"
    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    for line in proc.stdout:
        if name in line:
            if targ == 'win':
                pid = line.strip().split()[-1]
            else:
                pid = line.strip().split()[0]
            pids.append(pid)
    if len(pids):
        print 'Found following pids for', name
        print [_ for _ in pids]
    else:
        print 'No processes with', name, 'detected running for this user'
    return pids


def kill_prev_instances(targ, pids):
    for _ in pids:
        if targ == 'win':
            kill_cmd = ['wmic', 'process', 'where', 'processid=' + str(_), 'call', 'terminate']
        else:
            kill_cmd = ['kill', '-9', str(_)]
        print 'Killing pid ' + str(_)
        subprocess.check_call(kill_cmd, shell=False)
        time.sleep(2)

Some limitations for this code:

  1. It will only find processes started or owned by the running user. So run as Administrator to get all of them.
  2. You will need to get the exact string of the command line starting the SAP process. If this is not unique, the code above will not do what you need it to do.
  3. The code is made to work with Linux and Windows hosts, just set targ to win or remove the argument and the logic for Linux if you don't need them.
  4. To get the exact command line of your SAP process, open Task Manager, select Details, right click on the Name column header and select Select Columns then tick Command Line and press OK. All your user's processes now should also display their Command Line argument.
  5. The Command Line is something that was unique in my case, but if your process has some other defining characteristic, you can use that as your filter, so instead of ProcessId,CommandLine, use the attribute that makes your process unique (like Name or Description).
  6. Code was written for Python 2.7, but should work on 3, provided you remove/rewrite all the print statements.

That being said, just checking a process with a command line/name etc is running does not guarantee that that process is properly running and can take login requests. To do so, I would try to use a Python module that supports SAP connections. See the solutions given in this thread for further details. Can SAP work with Python?

BoboDarph
  • 2,751
  • 1
  • 10
  • 15