How to run an application under active session account from a Windows service using Delphi
To run an application from a service impersonating an user account, first we need to install "JEDI API Library & Security Code Library" as it contains different interesting OS callings which are really useful in order to achieve our purposes. Once the library has been unzipped, create your own service where the library is located and add the following paths to your search path in your project options:
Then instead of using CreateProcess function to execute an application, we need to use CreateProcessAsUser function. The new process runs in the security context of the user represented by the specified token. The service must be run by the LocalSystem account which is a predefined local account used by the service control manager. To be able to use the function from jedi-apilib which retrieves the token from the current user we need to use WTSQueryUserToken ( WtsGetActiveConsoleSessionID, hToken ) function. This function will only work under LocalSystem account which has SE_TCB_NAME property enabled, otherwise the query will be false.
Use the following example within your service:
Related links:
Then instead of using CreateProcess function to execute an application, we need to use CreateProcessAsUser function. The new process runs in the security context of the user represented by the specified token. The service must be run by the LocalSystem account which is a predefined local account used by the service control manager. To be able to use the function from jedi-apilib which retrieves the token from the current user we need to use WTSQueryUserToken ( WtsGetActiveConsoleSessionID, hToken ) function. This function will only work under LocalSystem account which has SE_TCB_NAME property enabled, otherwise the query will be false.
Use the following example within your service:
Related links:
Wrote about that while ago. Also with example project:
ReplyDeletehttp://www.cromis.net/blog/2010/01/how-to-start-a-gui-process-from-service-under-windows-vista7/
Thanks for letting me know. It is actually a very good article.
DeleteThanks very much for this example. This is the only working version in delphi i have found.
ReplyDeleteMuch less code and still working fine. Thanks again for share this code.
Glad that it helped!
DeleteRegards,
Jordi
Thank you for great such great article. Now I can actually make use of JEDI API.
ReplyDeleteThank you, great help.
ReplyDeleteI have noticed you are using the ttimer component, can I use any kind of none-visual components? for example a shell notification component should work? ate there any limitations?
Hi Zvika,
DeleteIt should be fine, you can use any kind of component.
Cheers,
Jordi
Thanks for the example! According to https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsqueryusertoken
ReplyDeleteYou must call closehandle to close the handle