1. jean-louis cantin
  2. PowerBuilder
  3. Wednesday, 3 July 2024 10:03 AM UTC

Good morning,
In a TSE (Terminal Server Edition) environment I have an application developed in PowerBuilder 19R3 that must launch another application. To do this I use the ShellExecuteEx function with the struc_shellexecuteinfo structure.


I thus recover the handle of the launched application.

My question is: How to close this remote application from my PowerBuilder application from this Handle?


Thanks for your help

jean-louis cantin Accepted Answer Pending Moderation
  1. Thursday, 4 July 2024 07:00 AM UTC
  2. PowerBuilder
  3. # 1

Hello everyone and thank you for all your answers. In fact my code quoted in my previous message does not work.
The return of the Eexcute function corresponds to the Handle of the application and not to its PID.
So I wanted to use the CloseHandle(ll_handle) function. The CloseHandle function returns to me True but does not close the application.
Does anyone know why the application does not close or how to recover the PID of an application launched from the ShellExecuteEx function?

Thank you for your help

Comment
  1. Francisco Martinez @Appeon
  2. Thursday, 4 July 2024 14:25 PM UTC
Can you share the signature of the ShellExecuteEx function?
  1. Helpful
  1. Francisco Martinez @Appeon
  2. Thursday, 4 July 2024 14:27 PM UTC
  1. Helpful
There are no comments made yet.
jean-louis cantin Accepted Answer Pending Moderation
  1. Thursday, 4 July 2024 06:10 AM UTC
  2. PowerBuilder
  3. # 2

Hello everyone,
Thanks for your advice.
Actually my code doesn’t work.
On the server, there are several instances of the application opened by different sessions and I would only close the one opened by my session.
The ideal would be to recover the PID of this application during its launch and to close it thanks to this PID.
But how to do this in PowerBuilder?

Comment
There are no comments made yet.
jean-louis cantin Accepted Answer Pending Moderation
  1. Wednesday, 3 July 2024 14:54 PM UTC
  2. PowerBuilder
  3. # 3

Hi Francisco,


Thank you for your advice, it was very useful.
Here is the code I used to validate your proposal and it works well:

 

Test code :

long ll_ret
ll_Ret = w_principal.wf_Execute("C:\Windows\System32\calc.exe", '', "open", false)
messagebox("Calculatrice ouverte", "PID = " + string(ll_ret))

ll_Ret = w_principal.wf_Execute("C:\Windows\System32\taskkill.exe", "/PID" + string(ll_Ret), "", false)
messagebox("Fermeture de la calculatrice", ll_ret)

 

detail of wf_Execute function :

//////////////////////////////////////////////////////////////////////////////
//LANCEMENT D'UNE COMMANDE SHELL SUR UN FICHIER DONNE
//Renvoi : une valeur < 32 si erreur
// si ab_Wait=true alors on renvoie le handle de la fenêtre ouverte
// sinon on renvoie le handle du process de l'application
//////////////////////////////////////////////////////////////////////////////
CONSTANT long SEE_MASK_NOCLOSEPROCESS = 64
CONSTANT long INFINITE = 4294967295 //&HFFFFFFFF

string ls_Class
long ll_ret
long ll_Handle
struc_shellexecuteinfo lstruc_shellexecuteinfo

lstruc_shellexecuteinfo.cbsize = 60
lstruc_shellexecuteinfo.fMask = SEE_MASK_NOCLOSEPROCESS // Ne ferme pas le process
lstruc_shellexecuteinfo.lpVerb = as_commande
lstruc_shellexecuteinfo.lpParameters = as_Parametres
lstruc_shellexecuteinfo.lpfile = as_fichier
lstruc_shellexecuteinfo.lpClass = ls_class
lstruc_shellexecuteinfo.nShow = SW_NORMAL

ll_ret = ShellExecuteEx(lstruc_shellexecuteinfo)
IF ll_ret = 0 THEN
//Erreur lors du lancement
RETURN lstruc_shellexecuteinfo.hInstapp
END IF

//Vérifie si on souhaite attendre l'ouverture de l'application pour continuer
if ab_Wait then
//Attend que l'application lancée reprenne la main et soit prete a être utilisée
WaitForInputIdle(lstruc_shellexecuteinfo.hprocess, INFINITE)

//Récupération du handle de la fenêtre se trouvant au premier plan (celle-ci doit être la fenêtre de l'application)
ll_Handle = GetForegroundWindow()

//Récupère le parent de la fenêtre récupérée pour que l'on soit sûr d'avoir la fenêtre Main de l'application
ll_Handle = wf_GetParent(ll_Handle)

return ll_Handle
end if

//Retourne le handle du process
return lstruc_shellexecuteinfo.hProcess

Comment
  1. Francisco Martinez @Appeon
  2. Wednesday, 3 July 2024 17:27 PM UTC
If you can ensure that your executable name is unique and there's only one instance running at the same time, you can use taskkill's /IM switch and pass the name of the process instead of having to keep track of the PID



Regards,

Francisco
  1. Helpful 1
  1. jean-louis cantin
  2. Thursday, 4 July 2024 07:02 AM UTC
Hello everyone and thank you for all your answers. In fact my code quoted in my previous message does not work.

The return of the Eexcute function corresponds to the Handle of the application and not to its PID.

So I wanted to use the CloseHandle(ll_handle) function. The CloseHandle function returns to me True but does not close the application.

Does anyone know why the application does not close or how to recover the PID of an application launched from the ShellExecuteEx function?



Thank you for your help
  1. Helpful
There are no comments made yet.
Francisco Martinez @Appeon Accepted Answer Pending Moderation
  1. Wednesday, 3 July 2024 14:26 PM UTC
  2. PowerBuilder
  3. # 4

Hi Jean-Louis,

This is just from the top of my head but, can't you use the same ShellExecuteEx to issue a taskkill command?

Alternatively, I would also consider adding some additional code to the target application that terminates other instances of its executable when passed a command line argument, and then issue the ShellExecuteEx instruction with this argument.

Just a couple of ideas.

 

Regards,
Francisco

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.