How Can a Windows Service Execute a Gui Application

How can a Windows service execute a GUI application?

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...

Starting GUI application from Windows Service - Approaches

After some trial and error coding for a day now, I've managed to debug and figure out what was causing errors in solution with using pInvoke to CreateProcessAsUser() method in advapi32.dll module.

As stated in the question itself, theres a topic on how to invoke GUI process from session 0 to current's user session using CreateProcessAsUser() method.

I've mistakenly ignored the working directory path to it, so some relative paths have not been working when GUI process was invoked, resulting in otherwise fully and nicely working implementation of StartProcessAsCurrentUser wrapper for CreateProcessAsUser() pInvoke.

The correct call for an app example is:

StartProcessAsCurrentUser(@"D:\Presentations\GUI.exe", null, @"D:\Presentations", true);

(where Presentations\GUI.exe is an example app. The null parameter is optional arguments parameter, and 3rd parameter is working directory, which I mistakenly always invoked as null.

I figure it might be helpful to leave this here, since there really aren't that many topics about invoking GUI application from service or session 0, or even remotely using ManagementClass instance method InvokeMethod("Create", {0});on a remote host, which works pretty much the same way.

Is there any way to start a GUI application from a windows service on Windows 7?

This change was made for a reason and not simply to annoy developers. The correct approach is to put your UI in a different program and communicate with the session through a pipe, or some other IPC mechanism. The recommendation that services do not present UI is more than 10 years old now.

You should really try to follow these rules, even though it may seem inconvenient to begin with. On the plus side you will enjoy the benefit of keeping your service logic and UI logic separate

If your services runs under the LOCALSYSTEM account then you can check "Allow service to interact with desktop", for the benefit of legacy services that would fail if they could not show UI. But it won't help you anyway because the UI will show in session 0 where it is never seen!

I recommend you take a read of the official Microsoft document describing session 0 isolation.

Best way to run Windows GUI application with privilege from daemon

Windows Services have not been designed to interact in current session (user session). Services are running into Session 0 since the deployment of Windows Vista.

Explanations about this changes can be found in "Impact of Session 0 Isolation on Services and Drivers in Windows".

I have found another Microsoft post "Launching an interactive process from Windows Service in Windows Vista and later" but we can read at the beginning:

The first thing you should do about it is that, don't do it. There are many limitations, bad implications and restrictions involved into it.

Windows Services are definitely a wrong solution for this use case. The unique solution that I can found is the Task Scheduler.

Run windows application from Windows service

This can be achieved simply by:

1)creating one console application.

2)Setup and deployment of Console application by making Output type as Windows Application from properties.

Code as follows:

static void Main(string[] args)
{
Timer t = new Timer(callback, null, 0, 60000);
Thread.Sleep(System.Threading.Timeout.Infinite);
}

// This method's signature must match the TimerCallback delegate
private static void callback(Object state)
{
try
{
bool isAppRunning = IsProcessOpen("APPName");
if (!isAppRunning)
{
Process p = new Process();
string strAppPath;
strAppPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles) + @"\FolderName\AppName.exe";
System.Diagnostics.Process.Start(strAppPath);
}
}
catch
{ }
}

public static bool IsProcessOpen(string name)
{
//here we're going to get a list of all running processes on
//the computer
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Contains(name))
{
//if the process is found to be running then we
//return a true
return true;
}
}
//otherwise we return a false
return false;
}

Launch an exe application from windows service

Thanks for the answers! I found out a solution for it and im posting it here.
I created a dummy app which is hidden on startup and it does the exact same function that the service was intended to.

1.create a dummy app (copy paste code from service to form application)
Hide it after start up.
2.start the application right after installation.
3.add registry key so that it starts up after a system reboot.

in simple words, clone service behavior.



Related Topics



Leave a reply



Submit