none
HOWTO Run a C#.NET.2.0 Windows Service to Programmatically interact with the desktop. RRS feed

  • Question

  • HOWTO Run a C#.NET.2.0 Windows Service to Programmatically interact with the desktop.

    Please help,

    I'm working with .NET 2.0 and C# and I need a windows service to be setup with its own account from the Service Control Manager, that in turn, will need to

    interact with the desktop. The service will launch windows applications, and need to use the various windows kernal functions like PostMessage, SendMessage,

    and SendMessageTimeout to communicate to processes it launches.

    This is not an issue on Windows Server 2008, where the windows service is setup from Service Control Manager (SCM) to use the local system account, and be

    allowed to "interact with the desktop". But the moment I try to use any account, even with full GOD/Admin privileges for the service, the calls to

    SendMessage fail.

    To my knowledge, the only steps I need is the THREAD in the service that launches the processes it wants to communicate to via SendMessage/PostMessage, is to

    do these steps:

    1) Create CreateWindowStation with all privileges.
              IntPtr_WinStationHandle = CreateWindowStation
              (
                "HealthPort.Workflow.Manager", 0, (uint) ACCESS_MASK.GENERIC_ALL, 0
              );
    2) Create a Desktop.
              IntPtr_DesktopHandle = CreateDesktop
              (
                "HealthPort.Workflow.Manager", null, null, 0, ACCESS_MASK.GENERIC_ALL, 0
              );
    3) Open the desktop with the inherit flag TRUE.
              IntPtr_OpenDesktopHandle = OpenDesktop
              (
                "HealthPort.Workflow.Manager", 0, true, ACCESS_MASK.GENERIC_ALL
              );

    I am not sure about the SetThreadDesktop, but I have tried that too.

    If some one could verify thes steps, that would be wonderful.

    As another approach, if I can not get the service to interact with the desktop programmatically, then I will leave the local system account on, with the

    checkbox in SCM checked for "itneract with the desktop", but have the service get credentials from some other place, and use them to impersonate the GOD

    account.


    =================================================================================
    Background
    =================================================================================

    I have tried several things to make this work, and all have failed. First, I made sure the service was setup to "interact with the desktop". This is done by

    setting the value called "Type" in the REGISTRY for the service (under HKLM\System\CurrentControlSet\Services\MyService to have the 256 bit flag set. I have

    since restarted my service (I have not rebooted) and it still will not interact with the desktop with the GOD account.

    As an FYI, I've also set the service's installer to turn the "interact with the desktop on" using such code:

              ConnectionOptions ConnectionOptions_Temp = new ConnectionOptions();
              ConnectionOptions_Temp.Impersonation = ImpersonationLevel.Impersonate;

              // CIMV2 is a namespace that contains all of the core OS and hardware classes.
              // CIM (Common Information Model) which is an industry standard for describing
              // data about applications and devices so that administrators and software
              // management programs can control applications and devices on different
              // platforms in the same way, ensuring interoperability across a network.

              ManagementScope ManagementScope_Temp = new ManagementScope
              (
                @"root\CIMV2", ConnectionOptions_Temp
              );
              ManagementScope_Temp.Connect();
              ManagementObject ManagementObject_WmiService;
              ManagementObject_WmiService = new ManagementObject
              (
                "Win32_Service.Name='HealthPort.Workflow.Manager.Service'"
              );
              ManagementBaseObject ManagementBaseObject_InParam = null;
              ManagementBaseObject_InParam = ManagementObject_WmiService.GetMethodParameters
              (
                "Change"
              );
              ManagementBaseObject_InParam["DesktopInteract"] = true;
              ManagementObject_WmiService.InvokeMethod("Change", ManagementBaseObject_InParam, null);

     

    I have also tried the following article to impersonate the desktop, but it is not wokring.

    http://www.codeproject.com/KB/system/ScreenMonitor.aspx

     

    Friday, September 16, 2011 5:11 PM

All replies