Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a Windows service execute a GUI application?

I have written a Windows service that allows me to remotely run and stop applications. These applications are run using CreateProcess, and this works for me because most of them only perform backend processing. Recently, I need to run applications that present GUI to the current log in user. How do I code in C++ to allow my service to locate the currently active desktop and run the GUI on it?

like image 925
sep Avatar asked Nov 06 '08 07:11

sep


People also ask

Can Windows service launch GUI application?

For this reason you cannot directly create a GUI from within the service, except if you run in legacy mode by flagging the Interact With Destop option, which is not good if you plan to run your service for some years in the future. As David Heffernan said, the best is to use a client-server architecture.

How do I make a Windows application GUI?

Click File > New, then select Dialog System Screenset on the New dialog box, and click OK. Click Yes on the message asking if you want to create a project. Select Windows GUI Project. Enter Welcome as the name of the project.

What is Windows GUI application?

The term "graphical user interface" (GUI), or simply "graphical interface", refers to a user interface using mouse, icons, and windows. When the term was first introduced, it was in contrast to command line interfaces and full-screen character interfaces.

Can a Windows service open a browser?

If you pass the url as execution argument to your service executable then you can open it with the default browser using Process.


2 Answers

Roger Lipscombe's answer, to use WTSEnumerateSessions to find the right desktop, then CreateProcessAsUser to start the application on that desktop (you pass it the handle of the desktop as part of the STARTUPINFO structure) is correct.

However, I would strongly recommend against doing this. In some environments, such as Terminal Server hosts with many active users, determining which desktop is the 'active' one isn't easy, and may not even be possible.

But most importantly, if an application will suddenly appear on a user's desktop, this may very well occur at a bad time (either because the user simply isn't expecting it, or because you're trying to launch the app when the session isn't quite initialized yet, in the process of shutting down, or whatever).

A more conventional approach would be to put a shortcut to a small client app for your service in the global startup group. This app will then launch along with every user session, and can be used start other apps (if so desired) without any juggling of user credentials, sessions and/or desktops.

Also, this shortcut can be moved/disabled by administrators as desired, which will make deployment of your application much easier, since it doesn't deviate from the standards used by other Windows apps...

like image 176
mdb Avatar answered Sep 19 '22 19:09

mdb


The short answer is "You don't", as opening a GUI program running under another user context is a security vulnerability commonly known as a Shatter Attack.

Take a look at this MSDN article: Interactive Services. It gives some options for a service to interact with a user.

In short you have these options:

  • Display a dialog box in the user's session using the WTSSendMessage function.

  • Create a separate hidden GUI application and use the CreateProcessAsUser function to run the application within the context of the interactive user. Design the GUI application to communicate with the service through some method of interprocess communication (IPC), for example, named pipes. The service communicates with the GUI application to tell it when to display the GUI. The application communicates the results of the user interaction back to the service so that the service can take the appropriate action. Note that IPC can expose your service interfaces over the network unless you use an appropriate access control list (ACL).

    If this service runs on a multiuser system, add the application to the following key so that it is run in each session: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. If the application uses named pipes for IPC, the server can distinguish between multiple user processes by giving each pipe a unique name based on the session ID.

like image 34
mlarsen Avatar answered Sep 19 '22 19:09

mlarsen