views:

1163

answers:

6

I have a program that installs a service, and I'd like to be able to give the user the option later on to change the startup type to "Automatic".

The OS is XP - if it makes any difference (Windows APIs?).

How can I do this in .NET? C# if possible! :)

+1  A: 

In the service installer you have to say

[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer 
{
    public ProjectInstaller()
    {
        ...
        this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
    }
}

You could also ask the user during installation and then set this value. Or just set this property in the visual studio designer.

Arthur
Ah OK, so it isn't possible post install without uninstalling the service?
joshcomley
You want to do that post install? Then you have to use WMI.
Arthur
A: 
ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller();
myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
CSharpAtl
A: 

In ProjectInstaller.cs, click/select the Service1 component on the design surface. In the properties windo there is a startType property for you to set this.

Matt Wrock
A: 

One way would be to uninstall previous service and install new one with updated parameters directly from your C# application.

You will need WindowsServiceInstaller in your app.

[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
    public WindowsServiceInstaller()
    {
        ServiceInstaller si = new ServiceInstaller();
        si.StartType = ServiceStartMode.Automatic; // get this value from some global variable
        si.ServiceName = @"YOUR APP";
        si.DisplayName = @"YOUR APP";
        this.Installers.Add(si);

        ServiceProcessInstaller spi = new ServiceProcessInstaller();
        spi.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
        spi.Username = null;
        spi.Password = null;
        this.Installers.Add(spi);
    }
}

and to reinstall service just use these two lines.

ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
lubos hasko
A: 

You can do it in the Installer class for the service by setting ServiceInstaller.StartType property to whatever value you get (you'll probably have to do this in a custom action since you want the user to specify) or you can modify the Service's "Start" REG_DWORD entry, the value 2 is automatic and 3 is manual. Its in HKEY_LOCAL_MACHINE\SYSTEM\Services\YourServiceName

SpaceghostAli
Modifying the registry would be the best way to change the startup type post-install. You can use the Microsoft.Win32.Registry class to do it.
Chris Tybur
Don't do that. Hacks like these are exactly the reason why there is tons of compatibility stuff in newer windows versions. There are perfectly reasonable APIs to do it - just that they are not managed. However when you know you are on windows (you know in both cases Registry or API/unmanged), that shouldn't matter.
Christian.K
How is using the registry the way it is meant to be used a hack? The API modifies the registry, its just a layer of abstraction...
SpaceghostAli
Well, if they ever need or want to change the (logical) layout of the registry for service registration, your code will break. So unless that part of the registry is explicitly document, and I doubt it is, it should be off-limits (aside manual troubleshooting, maybe).Besides, are you sure that the service control manager will actually recognize changes you make directly to the registry vs. those done via the official API?There might be a whole boatload of issues that only surface when you don't expect them.Just don't go down that road.
Christian.K
Well seeing that the API changes that registry value I'd say that the changes you are suggesting would break my code would also break the API. Did you even read the API docs you linked to? Because they mention the use of the registry...
SpaceghostAli
Yeah, I did read them. However, I didn't bother too much with the registry paths (which are not full documented nevertheless). But anyway, I stand corrected on this point. If the MSDN page mentions the paths, than probably it is rather save to use them.
Christian.K
A: 

You can use the OpenService() and ChangeServiceConfig() native Win32 APIs for that purpose. I believe that there is some information on pinvoke.net and of course on MSDN. You might want to check out the P/Invoke Interopt Assistant.

Christian.K