As it was shown before the service application itself can show nothing to users. The workaround seems obvious: as soon as service process can not be used as GUI then we need separate GUI processes:
In this scheme service application launches GUI process for every user when it is necessary. Service application and GUI communicates through some IPC channel, it may be COM, TCP/IP, named pipes and so on. The only this to be done is to implement some "simple" things:
session monitoring: we need to know when the GUI should be launched
GUI process launching
security context switching: we should not launch GUI in the LocalSystem security context
GUI process monitoring: user can close the GUI, we should launch it again if necessary
There two components that solve all these tasks smoothly:
This components monitors
sessions and fires events when new user session starts, when session closes and when session state changes.
This component is designed to start GUI process in given session. The most important thing is that the process is started in the security context of this session's user, not in the LocalSystem security context. And even more important is that it does not require user's login and password that is necessary to start process with CreateProcessAsUser. In addition this component takes care about all launched processes and fires event when processes state change.