Link to home
Start Free TrialLog in
Avatar of rakhy_rakey
rakhy_rakeyFlag for United States of America

asked on

Automate the check box "Allow service to interact with desktop"

Hi...

I have been working on the following issue since a week. If anybody help me to come out of this issue this is really really really a great and big help.

I developed a windows service. When I install it, it should check the check box "Allow service to interact with desktop" in the Logon tab of the properties of the windows servic and then it should start the service automatically.  It is doing it fine with my code. But it is not giving me the required output.

It is giving me required output, when I did it manually(Check the check box) and start the service.

Thank you very much,
Rakhy.


//for installation mode and service startup type
            this.Installers.Clear();
            _service = new ServiceInstaller();
            _service.ServiceName = strServiceName;
            _service.StartType = ServiceStartMode.Automatic;
            _service.Description = "Communicates between Client and Server with acknowledgement on both sides";
            this.Installers.Add(_service);

            _serviceProcess = new ServiceProcessInstaller();
            _serviceProcess.Account = ServiceAccount.LocalSystem;
            this.Installers.Add(_serviceProcess);

//part2: code to automate the check box "Allow service to interact with desktop"

RegistryKey ckey = Registry.LocalMachine.OpenSubKey(
              @"SYSTEM\CurrentControlSet\Services\VerizonClientServerWindowsService", true);

            if (ckey != null)
            {
                // Make sure the "Type" value is there, 

                //and then do bitwise operation on it.

               if (ckey.GetValue("Type") != null)
                {
                    ckey.SetValue("Type", ((int)ckey.GetValue("Type") | 256));
                }
              }


//part3: code to start the service

var controller = new ServiceController(strServiceName);
            controller.Start();
           



Case1: If I don't have part2 and part3, then I need to manually check the check box of "alllow to interact with desktop" and then start the service. In this case I am able to get my required output (able to display Form on desktop.) 

Case2: If I include part2 and part3, it is installing, checking the check box and running the service fine. 
But I am unable to get my required output(form on desktop) in this case.

Open in new window

Avatar of rambovn
rambovn
Flag of Germany image

Add a Project Installer to the service project.  ProjectInstaller.cs should have a serviceProcessInstaller and a serviceInstaller object on the design screen.  Add a Committed event handler for the serviceInstaller object with code similar to what I have below.  I have used this on a couple of services I wrote and it works for me.
private void serviceInstaller_Committed(object sender, InstallEventArgs e)
        {
            //Now set the "Allow Interact with Desktop" value so the service controller app 
            //will show in the system tray if the service starts it.
            ConnectionOptions coOptions = new ConnectionOptions();
            coOptions.Impersonation = ImpersonationLevel.Impersonate;
            ManagementScope mgmtScope = new ManagementScope(@"root\CIMV2", coOptions);
            mgmtScope.Connect();
            ManagementObject wmiService;
            wmiService = new ManagementObject("Win32_Service.Name='YourServiceName'");
            ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
            InParam["DesktopInteract"] = true;
            ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);
            wmiService.Dispose();
        }

Open in new window

Avatar of rakhy_rakey

ASKER

@rambovn

Thanks for the reply. I saw your link. Already I did that.

@Axshun

Thank you for the reply.
Already I have Service installer and service process installer objects.
Yes I added a committed event handler for the service installer object and I think your code is VB.NET.

My code is:
namespace ClientServer.WindowsService
{
    [RunInstaller(true)]
    public partial class WindowsServiceInstaller : Installer
    {

        string strServiceName = "Notification";
        private ServiceInstaller _service;
        private ServiceProcessInstaller _serviceProcess;
        public WindowsServiceInstaller()
        {

           // this.Installers.Clear();
            _service = new ServiceInstaller();
            _service.ServiceName = strServiceName;
            _service.StartType = ServiceStartMode.Automatic;
            _service.Description = "Communicates between Client and Server with acknowledgement on both sides";
            _service.Committed += new InstallEventHandler(ServiceInstaller_Committed); 
         

            _serviceProcess = new ServiceProcessInstaller();
            _serviceProcess.Account = ServiceAccount.LocalSystem;
           // _serviceProcess.Username = null;
            //_serviceProcess.Password = null;
            this.Installers.Add(_serviceProcess);
            this.Installers.Add(_service);
            AddPort ap = new AddPort();
        }


        void ServiceInstaller_Committed(object sender, InstallEventArgs e)
        {
            try
            {
              

                // Here is where we set the bit on the value in the registry.
                // Grab the subkey to our service

                RegistryKey ckey = Registry.LocalMachine.OpenSubKey(
                  @"SYSTEM\CurrentControlSet\Services\Notification", true);
                // Good to always do error checking!
                if (ckey != null)
                {
                    // Ok now lets make sure the "Type" value is there, 
                    //and then do our bitwise operation on it.
                    if (ckey.GetValue("Type") != null)
                    {
                        ckey.SetValue("Type", ((int)ckey.GetValue("Type") | 256));
                    }
                }
                // this.Committed += new InstallEventHandler(ServiceInstaller_Committed);
                var controller = new ServiceController(strServiceName);
                controller.Start();
               



            }
            catch (ArgumentException)
            {
            }

        }

    }
}

Open in new window

My code isn't Visual Basic, my code is all C#.  

Replace your event handler with mine and try it.  Remember to put the correct name of your service in the code in this line:

wmiService = new ManagementObject("Win32_Service.Name='YourServiceName'");
But I did not get it.

Even though it is checking the box and starting  the service programmatically, it is not giving the output.

But if I do it manually( stop the service, uncheck the check box, click Applu button, Click Ok button, Again go to properties --> Check the check box and Start the service), it is showing me the form.

It is killing me since 2 weeks. It is looking like big mystery for me.

I checked the registries too, by going to

SYSTEM\CurrentControlSet\Services\Notification.

When I compare value of Name ("Type") for both manually checking the check box and automatically, it showing me same.

Please help me regarding this.....

Thanks alot experts for your valuable replies....
What a quick reply Ashun...I am surprised...yeah...I will do that and will let you know...
ASKER CERTIFIED SOLUTION
Avatar of Chuck Yetter
Chuck Yetter
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Axshun....

Thanks alot....I really appreciate your help. I am almost cried to get this output since two weeks. You are expert in this field.

This forums is really helpful.

I will do my level best to help others through this forum. It is amazing. I am in trial membership and I will renew this and I recommend my friends that to join this forum.

Thanks alot...............

I have one more issue, if you can resolve.

I made a setup file to install the service. Let us say this is one version.

Later, I made some modifications to my service, and when I rebuild it, I got new version of setup file.

Here requirement from my project manager is, when I need to install new version, I should not uninstall the previous version using previously made setup file. The uninstall process of old version and installation process of new version should be done by the new version of setup file only.

Can I do that. If I can, what are the possible ways.

I really can not forget you man...U did a great help to me Axshun....

This guy is really great. The answer posted by this guy can not be found in any other forum on the internet. Really appreciated. Exact matching answer given by this guy. Fantastic and accurate. Mind blowing....
I didn't figure this out on my own, I am just passing along what I found when researching the same problem a couple years ago.  Glad to help though.
Yeah...Thanks alot.....It helped me alot....