HOWTO: Access the Application Desktop from a ServiceLast reviewed: September 11, 1997Article ID: Q173687 |
The information in this article applies to:
SUMMARYThe configuration of a Windows NT service determines how it may access the application desktop. The application desktop is named "default" and belongs to the "WinSta0" Window station object. The application desktop is associated with the interactively logged-on user. A process that has access to the application desktop can display message boxes, windows, and dialog boxes that can be seen visually by the interactively logged-on user. In addition, a process with access to the application desktop can send messages to other processes running on the desktop. The application desktop is not destroyed when the interactively logged-on user logs off. NOTE: Running interactive services under the LocalSystem 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 INFORMATIONA service that is configured in the LocalSystem account and is interacting with the desktop (the service type includes the SERVICE_INTERACTIVE_PROCESS flag) has access to the application desktop. A service that is configured in the LocalSystem account and is not interacting with the desktop does not have access to the application desktop by default. If the service needs to display information through a message box, you can do this by specifying one of the following two flag types:
MB_DEFAULT_DESKTOP_ONLY - The message box will appear on the application desktop, for example, "winsta0\default". MB_SERVICE_NOTIFICATION - The message box will appear on the currently active desktop.In addition, a service configured in the LocalSystem account can reconfigure its thread to access the application desktop. This is demonstrated in the following sample code. The sample code obtains handles to the "WinSta0" window station and the "default" desktop. Then it re- associates the current thread to the application desktop. Then the sample will display a message box and, when access to the interactive desktop is no longer needed, it resets the thread to the original window station and desktop. This must be done for every thread that wants access to the application desktop.
Sample Code
BOOL ThreadInteract(void) { HDESK hdeskCurrent; HDESK hdeskTest; HDESK hdesk; HWINSTA hwinstaCurrent; HWINSTA hwinsta; // // Save the current Window station // hwinstaCurrent = GetProcessWindowStation(); if (hwinstaCurrent == NULL) return FALSE; // // Save the current desktop // hdeskCurrent = GetThreadDesktop(GetCurrentThreadId()); if (hdeskCurrent == NULL) return FALSE; // // Obtain a handle to WinSta0 - service must be running // in the LocalSystem account // hwinsta = OpenWindowStation("winsta0", FALSE, WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES); if (hwinsta == NULL) return FALSE; // // Set the windowstation to be winsta0 // if (!SetProcessWindowStation(hwinsta)) return FALSE; // // Get the desktop // hdeskTest = GetThreadDesktop(GetCurrentThreadId()); if (hdeskTest == NULL) return FALSE; // // Get the default desktop on winsta0 // hdesk = OpenDesktop("default", 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); if (hdesk == NULL) return FALSE; // // Set the desktop to be "default" // if (!SetThreadDesktop(hdesk)) return FALSE; // // Do a message box // MessageBox(NULL, "MB_OK", "test_interact", MB_OK); // // Reset the Window station and desktop // if (!SetProcessWindowStation(hwinstaCurrent)) return FALSE; if (!SetThreadDesktop(hdeskCurrent)) return FALSE; // // Close the windowstation and desktop handles // if (!CloseWindowStation(hwinsta)) return FALSE; if (!CloseDesktop(hdesk)) return FALSE; return TRUE; }A service configured for a user account can access the application desktop through the message box types mentioned above. The above code will fail for a service configured for a user account due to security reasons but it will work for a service that impersonates the interactively logged-on user. For example, impersonation can be done through a named pipe connection from a process running on the application desktop. The service would have to impersonate the named pipe client. Keywords : BseService Version : WINDOWS NT:3.51,4.0 Platform : NT WINDOWS Issue type : kbhowto |
================================================================================
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |