|
|
||||||
|
#1
|
|
|
|
|
How do I set the ServiceType to InteractiveProcess, since this property is
read only? Is there a way to set this with code in my Installer class, or a standalone process? I normally set this manually in MMC by going to the Log On tab of the services properties, and selecting Allow service to interact with desktop. The end users want me to automate this in my install program, so that they don't have to do it manually. Bill |
|
|
|
#2
|
|
|
|
|
Hi Bill,
Thanks for posting in this group. In .Net this can not be done through program. Setting a windows as "interact with desktop" is a major security risk - windows services running in the background, logged on as a user different than the desktop user (and in the worst case, as LocalSystem), can be attacked from the desktop if they open UI. When they open UI, a rogue desktop app can send corrupted window messages to it, overrun buffers, and elevate privileges. ..Net Framework devlopment team has determined that allowing a service to interact with the desktop is a serious security risk. The property, 'ServiceType' is exposed ReadOnly in the ServiceController class so that we can list/enumerate existing services which are marked as 'InteractWithDesktop'. We deliberately made the property not settable in the installer because we do not support setting a service to 'InteractWithDesktop' in the framework. The workaround is to create a GUI app that communicates with the service using .NET remoting. This is a secure and supported way of doing what you want. For more information on remoting you can check out [url down]. Also the book "Wrox Professional C# (2nd Ed)" / Chapter 22 has examples and source code for of creating an NT service that communicates with graphical clients using TCP. Hope this helps, Best regards, Jeffrey Tan Microsoft Online Partner Support Get Secure! - [url down] This posting is provided "as is" with no warranties and confers no rights. -------------------- | From: "Bill Burris" <wburris> | Subject: ServiceController.ServiceType | Date: Tue, 18 Nov 2003 12:04:42 -0700 | Lines: 15 | X-Priority: 3 | X-MSMail-Priority: Normal | X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 | Message-ID: <OYxDZbgrDHA.2892> | Newsgroups: microsoft.public.dotnet.languages.csharp | NNTP-Posting-Host: kzin.phys.ualberta.ca 129.128.162.60 | Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTN GP10.phx.gbl | Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:200252 | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp | | How do I set the ServiceType to InteractiveProcess, since this property is | read only? | | Is there a way to set this with code in my Installer class, or a standalone | process? | | I normally set this manually in MMC by going to the Log On tab of the | services properties, and selecting Allow service to interact with desktop. | | The end users want me to automate this in my install program, so that they | don't have to do it manually. | | Bill | | | |
|
#3
|
|
|
|
|
""Jeffrey Tan[MSFT]"" <v-jetan> wrote in message
news:2140 > > We > deliberately made the > property not settable in the installer because we do not support setting a > service to 'InteractWithDesktop' in the framework. > > The workaround is to create a GUI app that communicates with the service > using .NET remoting. This is a secure and supported way of doing what you > want. For more information on remoting you can check out > [..]. Also the book "Wrox Professional > C# (2nd Ed)" / Chapter 22 has examples and source code for of creating an > NT service that communicates with graphical clients using TCP. > Thanks for the info. I have my application written as a separate program and use remoting for the service to communicate with the program. I used Ingo Rammer's Advanced .NET Remoting book to figure this out. This works great if the program is already running. The problem is when I need to launch the program remotely. The service will not launch the program using myProcess.Start(), if the service is not allowed to interact with the desktop. Our data acquisition systems (http://csr.phys.ualberta.ca/csr/research/alta.htm), are scattered all over the province at high schools. These systems are not on the internet so we connect to them using a modem. The program has a local GUI as well as a remote GUI. The remote GUI communicates with the program using remoting. Sometimes the program needs to be restarted, which is why I created a service for killing and launching the program remotely. It looks like the only real solution is to remove the GUI from my application and create a GUI as a separate application. If someone needs to interact with the program locally they can launch the GUI which communicates with the real app using remoting. Bill |
|
#4
|
|
|
|
|
Hi Bill,
Because windows service can not have the UI, you can not invoke the GUI directly. I think you should use remoting to invoke your GUI application. Best regards, Jeffrey Tan Microsoft Online Partner Support Get Secure! - [url down] This posting is provided "as is" with no warranties and confers no rights. |
|
#5
|
|
|
|
|
""Jeffrey Tan[MSFT]"" <v-jetan> wrote in message
news:3444 > > Hi Bill, > > Because windows service can not have the UI, you can not invoke the GUI > directly. I wasn't trying to put the GUI in the service, The service is starting up my application which has a GUI. > I think you should use remoting to invoke your GUI application. You can't use remoting to start the application, it needs to be running before the remoting server code is active. As a short term solution I could just edit the registry as shown in the article at: [url down] RegistryKey ckey = Registry.LocalMachine.OpenSubKey( @"SYSTEM\CurrentControlSet\Services\WindowsService 1", true); if(ckey != null) { if(ckey.GetValue("Type") != null) { ckey.SetValue("Type", ((int)ckey.GetValue("Type") | 256)); } } Second solution: I could create a simple control program whose purpose is to launch or kill my GUI app. The service will launch this control program. My remote application will talk to the control program using remoting. This additional layer between the service and my application should be less than a days work. Maybe this second solution won't solve anything, since the program in the middle will still be running on the same account as the service. The problem with remoting and windows services is that this 1% of my application seems to require a large amount of time digging around to get all the details worked out. Most of my remoting & service code, I got working back in Beta 2 days but the details keep coming back to haunt me. Bill |
|
#6
|
|
|
|
|
Hi Bill,
I am glad, you got some soluitons. For your second soluiton, as you said, you can not invoke GUI application through Process class in your service, how do you invoke your control program in your service? Is it a console application, so can be invoke? What does your control program "should be less than a days work." mean? I am just curious about your soluiton :-) Best regards, Jeffrey Tan Microsoft Online Partner Support Get Secure! - [url down] This posting is provided "as is" with no warranties and confers no rights. |
|
#7
|
|
|
|
|
The control program would be a console application. I would move most of
the code which currently resides in my service into the control program. The service would run the control program. The following code is my existing service. In my proposed solution the AltaManager class and the remoting setup code in OnStart would move into the control program. For this to work the control program and maybe the service would have to use the same user account that is normally used to run my application. namespace AltaService { public class AltaRemotingService : System.ServiceProcess.ServiceBase { private static EventLog evt = new EventLog( "Application" ); public static String SVC_NAME = "Alta Remote Manager"; public AltaRemotingService() { this.ServiceName = SVC_NAME; } static void Main() { evt.Source = SVC_NAME; evt.WriteEntry( "Alta Remoting Service initializing" ); ServiceBase.Run( new AltaRemotingService()); } protected override void OnStart(string[] args) { try { RemotingConfiguration.Configure( AppDomain.CurrentDomain.SetupInformation.Configura tionFile ); } catch( Exception e ) { evt.WriteEntry( e.Message, EventLogEntryType.Error ); } evt.WriteEntry( "Alta Remoting Service started" ); } protected override void OnStop() { evt.WriteEntry( "Alta Remoting Service stopped" ); } } public class AltaManager : MarshalByRefObject { private static EventLog evt = new EventLog( "Application" ); private Settings _settings; public AltaManager() { evt.Source = AltaRemotingService.SVC_NAME; } public void Startup() { LoadSettings(); Process myProcess = new Process(); myProcess.StartInfo.FileName = _settings.FileName; try { myProcess.Start(); } catch( Exception e ) { evt.WriteEntry( e.Message + " " + _settings.FileName, EventLogEntryType.Error ); } } public void Shutdown() { LoadSettings(); Process[] p; p = Process.GetProcessesByName( _settings.AppName ); if( p.Length == 0 ) { evt.WriteEntry( _settings.AppName + " process not found", EventLogEntryType.Error ); } else { try { for( int j = 0 ; j < p.Length ; j++ ) { if( p[j].Responding ) { p[j].CloseMainWindow(); } else { p[j].Kill(); } } } catch( Exception e ) { evt.WriteEntry( e.Message + " " + _settings.AppName, EventLogEntryType.Error ); } } } public bool Running { get { LoadSettings(); Process[] p; p = Process.GetProcessesByName( _settings.AppName ); if( p.Length == 0 ) { return( false ); } else { return( true ); } } } private void LoadSettings() { try { XmlSerializer serializer = new XmlSerializer( typeof(Settings) ); TextReader reader = new StreamReader( "AltaSettings.xml" ); _settings = (Settings)serializer.Deserialize( reader ); reader.Close(); } catch { _settings = new Settings(); SaveSettings(); } } private void SaveSettings() { XmlSerializer serializer = new XmlSerializer( typeof(Settings) ); TextWriter writer = new StreamWriter( "AltaSettings.xml" ); serializer.Serialize( writer, _settings ); writer.Close(); } } } I haven't tried creating the control program, since I am busy trying to figure out how to create an install program. I was thinking that I was going to have to write some code to call installutil and put that in as a custom action. Yesterday, down in the depths of the Creating Installation Components documentation, I discovered that all I have to do is add the exe which contains the service and Installer as a custom action. Its great that Visual Studio makes this so simple, too bad it wasn't easy to find the information in the documentation. Bill ""Jeffrey Tan[MSFT]"" <v-jetan> wrote in message news:3584 [..] |
|
#8
|
|
|
|
|
Hi Bill,
In .Net, it is easy to setup an installer application. .Net provides you much function support for this, please check: [url down] vbwlkwalkthroughcreatingwindowsserviceapplication. asp Hope this helps, Best regards, Jeffrey Tan Microsoft Online Partner Support Get Secure! - [url down] This posting is provided "as is" with no warranties and confers no rights. |
|
#9
|
|
|
|
|
Thanks for the help. Looks like I should take a look through the
walkthroughs, whenever I get a new version of Visual Studio. I wrote my service in 2001 using Beta 2 and was just trying to create a setup program for it now, more then 2 years later using VS 2003. Bill ""Jeffrey Tan[MSFT]"" <v-jetan> wrote in message news:3644 [..] |
|
#10
|
|
|
|
|
"Bill Burris" <wburris> wrote in message
news:a556 > > RegistryKey ckey = Registry.LocalMachine.OpenSubKey( > @"SYSTEM\CurrentControlSet\Services\WindowsService 1", true); > if(ckey != null) > { > if(ckey.GetValue("Type") != null) > { > ckey.SetValue("Type", ((int)ckey.GetValue("Type") | 256)); > } > } > That piece of code I posted before didn't work. It throws a System.UnauthorizedAccessException. Here is a piece of code which worked. Just add it to the Installer class. protected override void OnAfterInstall( IDictionary savedState ) { base.OnAfterInstall( savedState ); ConnectionOptions coOptions = new ConnectionOptions(); coOptions.Impersonation = ImpersonationLevel.Impersonate; ManagementScope mgmtScope = new System.Management.ManagementScope(@"root\CIMV2", coOptions); mgmtScope.Connect(); ManagementObject wmiService; ServiceController sc = new ServiceController( AltaRemotingService.SVC_NAME ); wmiService = new ManagementObject("Win32_Service.Name='" + sc.ServiceName + "'"); ManagementBaseObject InParam = wmiService.GetMethodParameters("Change"); InParam["DesktopInteract"] = true; ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null); sc.Start(); } You don't want to use this code unless you have to and know what you are doing, since it leaves a security hole in your system. Take a look at: [url down] Bill |
|
#11
|
|
|
|
|
Hi Bill,
Thanks for your feedback. I think it is very useful, and it will help many people in this community. Again thanks for your information. Best regards, Jeffrey Tan Microsoft Online Partner Support Get Secure! - [url down] This posting is provided "as is" with no warranties and confers no rights. |
|
|
| Similar Threads | |
| ServiceController?? Howdy! I am trying to write an application that will control some services I am writing. However, in VS 2008 (VB) I don't appear to have the... |
|
| Q: ServiceController Hi! I am using a ServiceController to start and stop my service. If i use the service localy and use the service controller it works fine. If i install the service on my... |
|
| ServiceController.GetServices( other pc ) Hi, On the 1.1 framework I couldn't find a solution to get a list of services from an other PC. Only a list of services on My local PC. (witch is strange i guess, as you... |
|
| ServiceController Dim myController As ServiceController myController = New ServiceController("myWrondName") i try : if myController is nothing then messagebox.show("This service doesn't... |
|
| Behind the scenes of ServiceController???? I want to know if ServiceController is a FULL MANAGE implementation or if is really a proxy over native api's or COM. Does anybody knows? Thanks in advance |
|
|
All times are GMT. The time now is 09:39 PM. | Privacy Policy
|