Como faço para alterar o tipo de boot de um serviço do Windows no .NET (pós-instalação)?

Eu tenho um programa que instala um serviço, e eu gostaria de ser capaz de dar ao usuário a opção mais tarde para alterar o tipo de boot para “Automatic”.

O sistema operacional é XP – se faz alguma diferença (APIs do Windows?).

Como posso fazer isso no .NET? C # se possível! 🙂

Você pode usar as APIs Win32 nativas OpenService () e ChangeServiceConfig () para essa finalidade. Eu acredito que há alguma informação sobre pinvoke.net e, claro, no MSDN . Você pode querer verificar o P / Invoke Interopt Assistant .

Eu escrevi um post no blog sobre como fazer isso usando P / Invoke. Usando a class ServiceHelper da minha postagem, você pode fazer o seguinte para alterar o Modo de Início.

var svc = new ServiceController("ServiceNameGoesHere"); ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic); 

No instalador de serviço você tem que dizer

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

Você também pode perguntar ao usuário durante a instalação e, em seguida, definir esse valor. Ou apenas defina essa propriedade no designer do visual studio.

Você pode usar o WMI para consultar todos os serviços e, em seguida, corresponder o nome do serviço ao valor do usuário inserido

Uma vez que o serviço foi encontrado basta alterar a propriedade StartMode

  if(service.Properties["Name"].Value.ToString() == userInputValue) { service.Properties["StartMode"].Value = "Automatic"; //service.Properties["StartMode"].Value = "Manual"; } 

// Isso fará com que todos os Serviços sejam executados em um Computador de Domínio e altere o Serviço “Apple Mobile Device” para o StartMode do Automatic. Essas duas funções devem obviamente ser separadas, mas é simples alterar um modo de início de serviço após a instalação usando o WMI

  private void getServicesForDomainComputer(string computerName) { ConnectionOptions co1 = new ConnectionOptions(); co1.Impersonation = ImpersonationLevel.Impersonate; //this query could also be: ("select * from Win32_Service where name = '" + serviceName + "'"); ManagementScope scope = new ManagementScope(@"\\" + computerName + @"\root\cimv2"); scope.Options = co1; SelectQuery query = new SelectQuery("select * from Win32_Service"); using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query)) { ManagementObjectCollection collection = searcher.Get(); foreach (ManagementObject service in collection) { //the following are all of the available properties //boolean AcceptPause //boolean AcceptStop //string Caption //uint32 CheckPoint //string CreationClassName //string Description //boolean DesktopInteract //string DisplayName //string ErrorControl //uint32 ExitCode; //datetime InstallDate; //string Name //string PathName //uint32 ProcessId //uint32 ServiceSpecificExitCode //string ServiceType //boolean Started //string StartMode //string StartName //string State //string Status //string SystemCreationClassName //string SystemName; //uint32 TagId; //uint32 WaitHint; if(service.Properties["Name"].Value.ToString() == "Apple Mobile Device") { service.Properties["StartMode"].Value = "Automatic"; } } } } 

Eu queria melhorar essa resposta … Um método para alterar startMode para computador especificado, serviço:

  public void changeServiceStartMode(string hostname, string serviceName, string startMode) { try { ManagementObject classInstance = new ManagementObject(@"\\" + hostname + @"\root\cimv2", "Win32_Service.Name='" + serviceName + "'", null); // Obtain in-parameters for the method ManagementBaseObject inParams = classInstance.GetMethodParameters("ChangeStartMode"); // Add the input parameters. inParams["StartMode"] = startMode; // Execute the method and obtain the return values. ManagementBaseObject outParams = classInstance.InvokeMethod("ChangeStartMode", inParams, null); // List outParams //Console.WriteLine("Out parameters:"); //richTextBox1.AppendText(DateTime.Now.ToString() + ": ReturnValue: " + outParams["ReturnValue"]); } catch (ManagementException err) { //richTextBox1.AppendText(DateTime.Now.ToString() + ": An error occurred while trying to execute the WMI method: " + err.Message); } } 

Em ProjectInstaller.cs, clique / selecione o componente Service1 na superfície de design. No windo das propriedades existe uma propriedade startType para você definir isto.

Que tal fazer uso de c: \ windows \ system32 \ sc.exe para fazer isso ?!

Em códigos VB.NET, use System.Diagnostics.Process para chamar sc.exe para alterar o modo de boot de um serviço do Windows. a seguir está o meu código de amostra

  Public Function SetStartModeToDisabled(ByVal ServiceName As String) As Boolean Dim sbParameter As New StringBuilder With sbParameter .Append("config ") .AppendFormat("""{0}"" ", ServiceName) .Append("start=disabled") End With Dim processStartInfo As ProcessStartInfo = New ProcessStartInfo() Dim scExeFilePath As String = String.Format("{0}\sc.exe", Environment.GetFolderPath(Environment.SpecialFolder.System)) processStartInfo.FileName = scExeFilePath processStartInfo.Arguments = sbParameter.ToString processStartInfo.UseShellExecute = True Dim process As Process = process.Start(processStartInfo) process.WaitForExit() Return process.ExitCode = 0 

Função final

 ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller(); myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic; 

Você pode fazê-lo na class Installer para o serviço, definindo a propriedade ServiceInstaller.StartType para qualquer valor que você obtiver (você provavelmente terá que fazer isso em uma ação personalizada desde que você deseja que o usuário especifique) ou você pode modificar o serviço ” Inicie a input “REG_DWORD”, o valor 2 é automático e 3 é manual. Está em HKEY_LOCAL_MACHINE \ SYSTEM \ Services \ YourServiceName

Uma maneira seria desinstalar o serviço anterior e instalar um novo com parâmetros atualizados diretamente do seu aplicativo C #.

Você precisará do WindowsServiceInstaller no seu aplicativo.

 [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); } } 

e para reinstalar o serviço basta usar essas duas linhas.

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