Fabio Di Paola

Da LotusScript a Windows e viceversa

16 Dicembre 2020 Domino Notes Sviluppo 0
sviluppo sito web

Una necessità abbastanza ricorrente in LotusScript lato server (quindi sul backend Domino) è la necessità di lanciare un programma esterno, ad esempio un convertitore di files o simile, aspettare la sua conclusione per poi andare a leggerne il risultato.
Andare a fare chiamate al kernel di Windows è naturalmente possibile ma qui voglio descrivere un approccio diverso che ha anche il vantaggio di aprire altre possibilità : l’interrogazione della WMI di Windows (
https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-start-page ) per avere la lista dei processi attivi .
Dico che apre possibilità aggiuntive perché questo tipo chiamata permette di interrogare la WMI per avere una serie di altre informazioni che possono essere utili in contesti diversi.

Eseguo quindi il programma esterno con la funzione SHELLID di Lotusscript (che è più facile da implementare rispetto una chiamata al kernel) e comunque ritorna il PID del processo lanciato –
La verifica che il PID sia ancora esistente e quindi il programma lanciato sia ancora attivo avviene andando ad interrogare il sistema operativo: in pratica mi connetto alla lista delle task e continuo a ciclare finchè il PID del programma lanciato continua ad apparire fra le task.

Questo è il pezzo di codice di esempio dove eseguo un fantomatico programma.exe (da sostituire con ciò che interessa eseguire e controllare) e poi inizio il ciclo Do While in cui interrogo la lista delle task, verifico se il PID esiste , in caso affermativo faccio una pausa di 2 secondi e rieseguo il ciclo. Quando il PID non compare più nella lista esco dal ciclo e posso proseguire con l’esecuzione del programma.
Consiglio di aggiungere un controllo sui tempi : se il ciclo Do While resta in loop per più di x secondi (a seconda del programma chiamato) conviene forzarne l’uscita e riportare un errore a LotusScript: probabilmente significa che il programma chiamato è a sua volta in loop o comunque ha dei problemi.

 

 
       
Dim strPC, strList
Dim StrSpace
Dim trovato As boolean
strPC = "."
ReturnValue = Shellid ( {programma.exe} , 3 ) 'lancia il programma e ritorna il PID dello stesso
Print "ShellId ritorna " + CStr(ReturnValue)
'crea l'oggetto di interfaccia alle task del sistema operativo
Set oWMIServ = GetObject("winmgmts:{impersonationLevel=impersonate}!\\"& strPC & "\root\cimv2") 

Do While true 'questo è il ciclo che interroga continuamente la lista delle task
  'interroga le task presenti
   Set colProc = oWMIServ.ExecQuery("Select * from Win32_Process") 
   trovato = false
   Forall oProc In colProc  ' cicla le task trovate
     If CInt(oProc.ProcessId) = CInt(ReturnValue) Then 'verifica se la task esiste
         Print oProc.ProcessId + " - " + oProc.Name
         Print oProc.Name +" ancora attivo"
         trovato = true
     End If
   End ForAll
   If trovato = false Then Exit Do  ' se non ha trovato la task esce dal ciclo
   ' questo si può tenere, modificare o togliere : è la pausa in secondi fra ogni ciclo di controllo
   Sleep 2    
Loop