Ответ 1
Для этой цели вы можете использовать собственные API Win32 для OpenService() и ChangeServiceConfig(). Я считаю, что есть некоторая информация о pinvoke.net и, конечно же, MSDN. Вы можете проверить P/Invoke Interopt Assistant.
У меня есть программа, которая устанавливает службу, и я хотел бы дать пользователю возможность позже включить изменение типа запуска на "Автоматически".
ОС - это XP - если это имеет значение (Windows API?).
Как это сделать в .NET? С# если возможно!:)
Для этой цели вы можете использовать собственные API Win32 для OpenService() и ChangeServiceConfig(). Я считаю, что есть некоторая информация о pinvoke.net и, конечно же, MSDN. Вы можете проверить P/Invoke Interopt Assistant.
Я написал сообщение в блоге о том, как это сделать, используя P/Invoke. Используя класс ServiceHelper из моего сообщения, вы можете сделать следующее, чтобы изменить режим запуска.
var svc = new ServiceController("ServiceNameGoesHere");
ServiceHelper.ChangeStartMode(svc, ServiceStartMode.Automatic);
В программе установки вы должны сказать
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
...
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
}
}
Вы также можете попросить пользователя во время установки, а затем установить это значение. Или просто установите это свойство в дизайнере визуальной студии.
Вы можете использовать WMI для запроса всех сервисов, а затем сопоставить имя сервиса с введенным значением пользователя
Как только служба найдена, просто измените свойство StartMode
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";
}
}
}
}
Я хотел улучшить этот ответ... Один из способов изменить startMode для указанного компьютера, службы:
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);
}
}
В ProjectInstaller.cs щелкните/выберите компонент Service1 на поверхности дизайна. В свойствах windo есть свойство startType, которое вы можете установить.
Как использовать c:\windows\system32\sc.exe для этого?!
В коде VB.NET используйте System.Diagnostics.Process для вызова sc.exe для изменения режима запуска службы Windows. следующий мой пример кода
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
Конечная функция
ServiceInstaller myInstaller = new System.ServiceProcess.ServiceInstaller();
myInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
Вы можете сделать это в классе Installer для службы, установив свойство ServiceInstaller.StartType на любое значение, которое вы получаете (вам, вероятно, придется сделать это в пользовательском действии, так как вы хотите, чтобы пользователь указал) или вы можете изменить запись "Start" REG_DWORD "Сервис", значение 2 является автоматическим, а 3 - ручным. Его в HKEY_LOCAL_MACHINE\SYSTEM\Services\YourServiceName
Один из способов - удалить предыдущую службу и установить новую с обновленными параметрами непосредственно из вашего приложения С#.
Вам понадобится WindowsServiceInstaller
в вашем приложении.
[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);
}
}
и для переустановки службы просто используйте эти две строки.
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });