Comment modifier le type de démarrage D'un service Windows in.NET (post-installation)?
J'ai un programme qui installe un service, et j'aimerais pouvoir donner à l'utilisateur la possibilité de changer le type de démarrage en "Automatique".
Le système D'exploitation est XP - si cela fait une différence (API Windows?).
Comment puis-je faire cela dans. Net? C # si possible! :)
9 réponses
Vous pouvez utiliser les API Win32 natives OpenService() et ChangeServiceConfig() à cette fin. Je crois qu'il y a quelques informations sur pinvoke.net et, bien sûr, sur MSDN. Vous pouvez consulter le P/Invoke Interopt Assistant .
J'ai écrit un article de blog sur la façon de le faire en utilisant P / Invoke. En utilisant la classe ServiceHelper de mon post, vous pouvez faire ce qui suit pour changer le Mode de démarrage.
var svc = new ServiceController("ServiceNameGoesHere");
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
Dans le programme d'installation du service, vous devez dire
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
...
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
}
}
Vous pouvez également demander à l'utilisateur lors de l'installation, puis définir cette valeur. Ou définissez simplement cette propriété dans visual studio designer.
Vous pouvez utiliser WMI pour interroger tous les services, puis faire correspondre le nom du service à la valeur utilisateur entrée
Une fois le service trouvé, modifiez simplement la propriété StartMode
if(service.Properties["Name"].Value.ToString() == userInputValue)
{
service.Properties["StartMode"].Value = "Automatic";
//service.Properties["StartMode"].Value = "Manual";
}
/ / Ceci obtiendra tous les Services s'exécutant sur un ordinateur de domaine et changera le Service "appareil mobile D'Apple" au StartMode D'automatique. Ces deux fonctions doivent évidemment être séparées, mais il est simple de changer un mode de démarrage de service après l'installation en utilisant 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";
}
}
}
}
Je voulais pour améliorer cette réponse... Une méthode pour changer startMode pour L'ordinateur spécifié, service:
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);
}
}
Dans ProjectInstaller.cs, cliquez sur / sélectionnez le composant Service1 sur la surface de conception. Dans les propriétés windo, il y a une propriété startType pour que vous puissiez définir ceci.
Que diriez-vous de faire usage de c:\windows\system32\sc.exe pour faire ça ?!
Dans VB.NET Codes, utilisez le système.Diagnostic.Processus pour appeler sc.exe pour changer le mode de démarrage d'un service windows. voici mon exemple de code
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
Fonction De Fin
ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller();
myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
Vous pouvez le faire dans la classe D'installation du service en définissant ServiceInstaller.Propriété StartType à la valeur que vous obtenez (vous devrez probablement le faire dans une action personnalisée puisque vous voulez que l'utilisateur spécifie) ou vous pouvez modifier L'entrée REG_DWORD" Start " du Service, la valeur 2 est automatique et 3 est manuelle. C'est dans HKEY_LOCAL_MACHINE \ SYSTEM \ Services \ YourServiceName
Une façon serait de désinstaller le service précédent et d'en installer un nouveau avec des paramètres mis à jour directement à partir de votre application C#.
, Vous aurez besoin de WindowsServiceInstaller
dans votre application.
[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);
}
}
Et pour réinstaller le service, utilisez simplement ces deux lignes.
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });