Launching GUI App from Windows Service - Window Does Not Appear

梦想的初衷 提交于 2019-11-30 20:47:50

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;
}

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)

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.

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

Like already mentioned from the others a windows service is "normally" running under a separate account ("LocalSystem" or "NetworkService"). This is the reason why you might no see the UI of the program started by your service. Also services are not intended to have a UI, they act as a background service.

But also note that starting a application by a service can be a high security risk, because the application is running with the same privileges than your service is. Normally this would be the local system account.

I don't know what your are trying to achieve with your service, but consider to use the autostart function of windows instead of a service to run your application.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!