Reputation: 28808
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! :)
Upvotes: 37
Views: 61384
Reputation: 2763
You can use WMI to query all services and then match the service name to the inputted user value
Once the service has been found just change the StartMode Property
if(service.Properties["Name"].Value.ToString() == userInputValue)
{
service.Properties["StartMode"].Value = "Automatic";
//service.Properties["StartMode"].Value = "Manual";
}
//This will get all of the Services running on a Domain Computer and change the "Apple Mobile Device" Service to the StartMode of Automatic. These two functions should obviously be separated, but it is simple to change a service start mode after installation using 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";
}
}
}
}
I wanted to improve this response... One method to change startMode for Specified computer, 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);
}
}
Upvotes: 7
Reputation: 61
How about make use of c:\windows\system32\sc.exe to do that ?!
In VB.NET Codes, use System.Diagnostics.Process to call sc.exe to change the startup mode of a windows service. following is my sample 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
End Function
Upvotes: 3
Reputation: 14391
I wrote a blog post on how to do this using P/Invoke. Using the ServiceHelper class from my post you can do the following to change the Start Mode.
var svc = new ServiceController("ServiceNameGoesHere");
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
Upvotes: 64
Reputation: 49220
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.
Upvotes: 10
Reputation: 8392
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
Upvotes: 0
Reputation: 25052
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 });
Upvotes: -3
Reputation: 6640
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.
Upvotes: 2
Reputation: 7512
ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller();
myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
Upvotes: -1
Reputation: 8129
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.
Upvotes: 15