Launching GUI App from Windows Service - Window Does Not Appear

12,283

Solution 1

Services run in other session on Vista or later and applications started directly from services are started in the same session by default. Starting applications in other sessions is possible - you have to find the id of the user session and use CreateProcessAsUser.

If more than one user is logged in and you need to start your program for all users you must find the ids of all sessions.

Here is sample code:

int session = Win32.WTSGetActiveConsoleSessionId();
if (session == 0xFFFFFFFF)
{
    return false;
}

IntPtr userToken;
bool res = Win32.WTSQueryUserToken(session, out userToken);
if (!res)
{
    this.log.WriteEntry("Error WTSQueryUserToken");
    return false;
}

string path = GetPath();
string dir = Path.GetDirectoryName(path);
Win32.STARTUPINFO si = new Win32.STARTUPINFO();
si.lpDesktop = "winsta0\\default";
si.cb = Marshal.SizeOf(si);

Win32.PROCESS_INFORMATION pi = new Win32.PROCESS_INFORMATION();
Win32.SECURITY_ATTRIBUTES sa = new Win32.SECURITY_ATTRIBUTES();
sa.bInheritHandle = 0;
sa.nLength = Marshal.SizeOf(sa);
sa.lpSecurityDescriptor = IntPtr.Zero;

if (!Win32.CreateProcessAsUser(userToken,       // user token
                                path,           // exexutable path
                                string.Empty,   // arguments
                                ref sa,         // process security attributes ( none )
                                ref sa,         // thread  security attributes ( none )
                                false,          // inherit handles?
                                0,              // creation flags
                                IntPtr.Zero,    // environment variables
                                dir,            // current directory of the new process
                                ref si,         // startup info
                                out pi))        // receive process information in pi
{
    int error = Marshal.GetLastWin32Error();
    this.log.WriteEntry("Error CreateProcessAsUser:" + error);
    return false;
}

Solution 2

Services are run under different account privileges (LocalService/NetworkService etc)and hence they don't have access to your desktop (under your login account's control).

Services are meant to do their job silently and thats what they should do. (with the exception of logging something in windows event log when they have something important to say)

Solution 3

If you open your service's properties window, go to the Log On tab then check the "Allow service to interact with desktop" check box you will get the behavior you want. Also depending on what app you what to run you may need to change the log on account.

Solution 4

Services are not interactive by definition, so you shouldn't expect any user interface elements to show when you launch an application from a service.

It's by design...

Share:
12,283
Admin
Author by

Admin

Updated on June 16, 2022

Comments

  • Admin
    Admin almost 2 years

    I have written a simple windows service which will launch a exe specified in the onstart() method of the service. After starting the service the exe got launched it only presents in the memory but it doesnt show in the explorer.

    I'm trying to launch a calc.exe from my code.it shows the exe in the memory but it doesnt comes into my view(i.e) in the explorer.

    Below is my code to launch the exe in the onStart() method

        Process pr=new Process();
        pr.StartInfo.FileName="calc.exe";
        pr.StartInfo.WindowStyle=ProcessWindowStyle.Maximized;
        pr.StartInfo.CreateNoWindow=false;
        pr.Start();
    //  pr.WaitForExit();
    
  • MSalters
    MSalters almost 15 years
    Also, Task Manager by default shows only the processes running under your login account.