0

Context : I have two open sessions in my SAP GUI with following id :

  • /app/con[0]/ses[0]
  • /app/con[0]/ses[1]

I want to run 1 script (vbs) in each session, this is my code :

foreach (GuiSession s in _dicSap[tmpDKey].get_lstSapSession())
{
    if (!s.Busy)
    {
        Process p = Process.Start(scriptName, s.Id); //s.Id=/app/con[0]/ses[0]
        await Task.Delay(5000);
        break;
    }
}

Problem : my scripts are correctly executed but they are execute one by one. I want to run those scripts in simultaneously. I don't understand because I haven't use .WaitForExit().

Is it my code which is wrong or is it impossible to run multi-script in SAP GUI in C# ?

Sorry for my english. Regards

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Corentin Cl
  • 1
  • 1
  • 3

1 Answers1

0

might be necro-threading, but this is how I solved a similar problem. In my case I had to run N tasks, not two. Please also note that I had the script steps in c# code, not in separate files. Anyhow, this solution should fit your requirements.

  1. First of all, you'll need to create multiple sessions of an existing (initial) session:

    for (int i = 0; i < numOfSessions - 1 ; i++)
        {
            SapSession.CreateSession();
        }
    

All these sessions will be placed in a list (sessionList). I use a custom sessionDetails class because I need to store IDs and activity information:

for (int i = 0; i < _maxSessions; i++)
 {
     sessionDetail sd = new sessionDetail((GuiSession)sapConnection.Sessions.Item(i), false, i);
     sessionList.Add(sd);
 }


class sessionDetail
{
    public GuiSession sapSession { get; }
    public bool isUsed { get; set; }
    public int sessionId { get; set; }

    public sessionDetail(GuiSession SapSession, bool IsUsed, int SessionId)
    {
        sapSession = SapSession;
        isUsed = IsUsed;
        sessionId = SessionId;
    }

}
  1. Secondly you'll need to parallelize execution of your program. Let’s assume you’ve got an array of scripts scr that you need to execute:

        string[] scr = { "scriptingTask1", " scriptingTask2", " scriptingTask3" };
    

Then you’ll create parallel threads for each script:

        Parallel.ForEach<string>(scr
                 , new ParallelOptions { MaxDegreeOfParallelism = _maxSessions }
                 , (script) => DoSomeWork(script, sessionList)
                 );
  1. The method that you pass for a lambda will assign the scripting Tasks to sessions and launch them

    private void DoSomeWork(string scrptTask, List<sessionDetail> _sessionList)
    {
        sessionDetail _sessionToUse;
        foreach (sessionDetail s in _sessionList)
        {
            if (!s.isUsed)
            {
                _sessionToUse = s;
                s.isUsed = true;
    
                //// Do your stuff here
    
                s.isUsed = false;
                break;
            }
        }
    }
    
  2. Fourth, make sure that addresses in your scripts (like "/app/con[0]/ses[0]/wnd[0]/usr/ctxtP_EKORG”) use corresponding session IDs in them. You can see it in the middle of this path (ses[0]). If you keep referencing ses[0] in all the scripts, you'll likely get "element wasn't found by ID" errors.

Constantine.