Accessing the Application Desktop from a Service (115825)



The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API), when used with:
    • the operating system: Microsoft Windows NT 3.5
    • the operating system: Microsoft Windows NT 3.51

This article was previously published under Q115825

SUMMARY

Under Windows NT, version 3.1, if you want a service to have access to the application desktop, you must run the service in the LocalSystem account. A service process running in the LocalSystem account (or a process started from such a service) can display message boxes, windows, and dialog boxes. Processes that are running in the LocalSystem account are not terminated by the system during logoff. A number of changes were made to Windows NT, version 3.5, that affect the way Windows NT interacts with these services. In addition, Windows NT 3.51 has a richer set of desktop APIs.

NOTE: Running interactive services under the system account is a VERY dangerous practice. This is especially true of the command processor and batch files. A user who wants to control the system can just hit CTRL+C to get an interactive system command prompt.

MORE INFORMATION

The following are new features of Windows NT, version 3.5, that affect services:
  • The account of the logged in user is the only account granted access to the application desktop. The LocalSystem no longer has access. Therefore, it is possible to get access to the desktop by impersonating the user before making any USER or GDI calls.
  • Console and GUI applications started from a service process during a particular logon session are run on an invisible window station and desktop that are unique to that session. The window station and desktop are created automatically when the first application in the session starts; they are destroyed when the last application exits. There is no way to make these invisible desktops visible.
  • If you want a service in the localsystem account to interact with the logged-on user, specify the SERVICE_INTERACTIVE_PROCESS flag in the call to CreateService(). For example:
          schService = CreateService(
             schSCManager,
             serviceName,
             serviceName,
             SERVICE_ALL_ACCESS,
             SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS,
             SERVICE_DEMAND_START,
             SERVICE_ERROR_NORMAL,
             lpszBinaryPathName,
             NULL,
             NULL,
             NULL,
             NULL,
             NULL );
    						
    If you specify an account other than localsystem when using SERVICE_INTERACTIVE_PROCESS, you will get error INVALID_PARAMETER (87).
  • If you use CreateProcess() to launch your process and you want your service to log onto the users desktop, assign the lpdesktop parameter of the STARTUPINFO struct with "WinSta0\\Default".
  • Services that simply need a visible user notification can do this by calling MessageBox() with the MB_SERVICE_NOTIFICATION flag. Using the MB_DEFAULT_DESKTOP_ONLY flag works as well, but only if the user's desktop is active. If the workstation is locked or a screen saver is running, the call will fail.

    NOTE: If you are writing code for an application that can be run as either a service or an executable, you can't use MB_SERVICE_NOTIFICATION as well as a non-NULL hwndOwner.
  • Any output done to a window is not displayed or made available to the application in any way. Attempts to read bits from the display results in a failure.
  • GUI services do not receive WM_QUERYENDSESSION/WM_ENDSESSION messages at logoff and shutdown; instead, they receive CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT events. These services are not terminated by the system at logoff.

Modification Type:MajorLast Reviewed:3/16/2004
Keywords:KB115825