2009-09-25 15 views

risposta

8

È possibile utilizzare le API Win32 native OpenService() e ChangeServiceConfig() per tale scopo. Credo che ci siano alcune informazioni su pinvoke.net e ovviamente su MSDN. Potresti voler controllare lo P/Invoke Interopt Assistant.

+6

Downnoter: sarebbe utile se ti interessasse spiegarti. –

9

Nel programma di installazione del servizio che hai da dire

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

Si potrebbe anche chiedere l'utente durante l'installazione e quindi impostare questo valore. O semplicemente imposta questa proprietà nel designer dello studio visivo.

+0

Ah OK, quindi non è possibile dopo l'installazione senza disinstallare il servizio? – joshcomley

+0

Vuoi fare quell'installazione post? Quindi devi usare WMI. – Arthur

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

In ProjectInstaller.cs, fare clic/selezionare il componente Service1 sulla superficie di progettazione. Nelle proprietà windo è disponibile una proprietà startType per impostarla.

-2

Un modo sarebbe disinstallare il servizio precedente e installarne uno nuovo con i parametri aggiornati direttamente dall'applicazione C#.

Avrete bisogno di WindowsServiceInstaller nella vostra 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); 
    } 
} 

e per reinstallare il servizio basta utilizzare queste due linee.

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

Si può fare nella classe di installazione per il servizio impostando la proprietà ServiceInstaller.StartType a qualsiasi valore che si ottiene (probabilmente dovrete fare questo in un'azione personalizzata da quando si desidera che l'utente di specificare) oppure è possibile modificare la voce REG_DWORD "Start" del servizio, il valore 2 è automatico e 3 è manuale. È in HKEY_LOCAL_MACHINE \ SYSTEM \ Services \ YourServiceName

+0

La modifica del registro sarebbe il modo migliore per modificare il tipo di avvio dopo l'installazione. È possibile utilizzare la classe Microsoft.Win32.Registry per farlo. –

+2

Non farlo. Hacks come questi sono esattamente la ragione per cui ci sono tonnellate di compatibilità nelle versioni di Windows più recenti. Ci sono API perfettamente ragionevoli per farlo - solo che non sono gestite. Tuttavia, quando sai di essere su Windows (sai in entrambi i casi Registry o API/Unmanged), ciò non dovrebbe avere importanza. –

+0

Come si usa il registro nel modo in cui si intende utilizzare un hack? L'API modifica il registro, è solo un livello di astrazione ... – SpaceghostAli

47

Ho scritto un blog post su come utilizzare P/Invoke. Utilizzando la classe ServiceHelper del mio post, è possibile effettuare le seguenti operazioni per modificare la modalità di avvio.

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

Funziona perfettamente su XP! Funzionerà su Windows 7, ecc.? – Tom

+0

@ Tom non l'ho provato su Win7 quindi non posso dirlo con certezza ... –

+2

Ho provato questo in alcune macchine virtuali, e tutto sembra funzionare bene in Win 7. Grazie ancora. – Tom

5

È possibile utilizzare WMI per interrogare tutti i servizi e quindi corrispondere al nome del servizio per il valore immesso dall'utente

Una volta che il servizio è stato trovato solo cambiare lo StartMode proprietà

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

       } 

// Ciò consentirà di ottenere tutti i servizi in esecuzione su un computer di dominio e di modificare il servizio "Dispositivo mobile Apple" sulla StartMode di Automatic. Queste due funzioni devono ovviamente essere separate, ma è semplice per cambiare una modalità di avvio del servizio dopo l'installazione utilizzando 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"; 

       } 
      } 
     }   
    } 

volevo migliorare questa risposta ...Un metodo per cambiare startMode per computer specificato, il servizio:

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

Che ne dite di fare uso di c: \ windows \ system32 \ sc.exe per farlo?!

Nei codici VB.NET, utilizzare System.Diagnostics.Process per chiamare sc.exe per modificare la modalità di avvio di un servizio di Windows. segue è il mio codice di esempio

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 

End Function

Problemi correlati