There's an error in the QUERY_SERVICE_CONFIG struct I posted earlier. The string members should have the MarshalAs attribute set to UnmanagedType.LPStr instead of UnmanagedType.LPWStr
Here's the new Struct definition (also updated in original post)
Please note that when using WMI, the WMI service must be running. It's running by default, so if you are 100% certain that the user won't stop op disable it, it will always work.
Here's a class you can use to do the same with the Win32 api. Just copy the code below into a class file & use the following code to try it (it will set the startup type of the messenger service to 'Manual'):
//A device driver started by the system loader. This value is valid only for driver services.
SERVICE_SYSTEM_START = 0x00000001,
//A device driver started by the IoInitSystem function. This value is valid only for driver services.
SERVICE_AUTO_START = 0x00000002,
//A service started automatically by the service control manager during system startup.
SERVICE_DEMAND_START = 0x00000003,
//A service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED = 0x00000004
//A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED.
}
[Flags]
public enum ServiceControlAccessRights : int {
SC_MANAGER_CONNECT = 0x0001,
//Required to connect to the service control manager.
SC_MANAGER_CREATE_SERVICE = 0x0002,
//Required to call the CreateService function to create a service object and add it to the database.
SC_MANAGER_ENUMERATE_SERVICE= 0x0004,
//Required to call the EnumServicesStatusEx function to list the services that are in the database.
SC_MANAGER_LOCK = 0x0008,
//Required to call the LockServiceDatabase function to acquire a lock on the database.
SC_MANAGER_QUERY_LOCK_STATUS = 0x0010,
//Required to call the QueryServiceLockStatus function to retrieve the lock status information for the database
SC_MANAGER_MODIFY_BOOT_CONFIG= 0x0020,
//Required to call the NotifyBootConfigStatus function.
SC_MANAGER_ALL_ACCESS = 0xF003F
//Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights in this table.
}
[Flags]
public enum ServiceAccessRights : int {
SERVICE_QUERY_CONFIG = 0x0001,
//Required to call the QueryServiceConfig and QueryServiceConfig2 functions to query the service configuration.
SERVICE_CHANGE_CONFIG = 0x0002,
//Required to call the ChangeServiceConfig or ChangeServiceConfig2 function to change the service configuration. Because this grants the caller the right to change the executable file that the system runs, it should be granted only to administrators.
SERVICE_QUERY_STATUS = 0x0004,
//Required to call the QueryServiceStatusEx function to ask the service control manager about the status of the service.
SERVICE_ENUMERATE_DEPENDENTS = 0x0008,
//Required to call the EnumDependentServices function to enumerate all the services dependent on the service.
SERVICE_START = 0x0010,
//Required to call the StartService function to start the service.
SERVICE_STOP = 0x0020,
//Required to call the ControlService function to stop the service.
SERVICE_PAUSE_CONTINUE = 0x0040,
//Required to call the ControlService function to pause or continue the service.
SERVICE_INTERROGATE = 0x0080,
//Required to call the ControlService function to ask the service to report its status immediately.
SERVICE_USER_DEFINED_CONTROL = 0x0100,
//Required to call the ControlService function to specify a user-defined control code.
SERVICE_ALL_ACCESS = 0xF01FF
//Includes STANDARD_RIGHTS_REQUIRED in addition to all access rights in this table.
}
[Flags]
public enum ServiceType : uint {
SERVICE_KERNEL_DRIVER = 0x00000001,
//Driver service.
SERVICE_FILE_SYSTEM_DRIVER = 0x00000002,
//File system driver service.
SERVICE_WIN32_OWN_PROCESS = 0x00000010,
//Service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS = 0x00000020,
//Service that shares a process with other services.
SERVICE_INTERACTIVE_PROCESS = 0x00000100,
//The service can interact with the desktop.
SERVICE_NO_CHANGE = 0xffffffff
}
public enum ServiceErrorControl : uint
{
SERVICE_ERROR_IGNORE = 0x00000000,
//The startup program ignores the error and continues the startup operation.
SERVICE_ERROR_NORMAL = 0x00000001,
//The startup program logs the error in the event log but continues the startup operation.
SERVICE_ERROR_SEVERE = 0x00000002,
//SERVICE_ERROR_CRITICAL = 0x00000003, //The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
SERVICE_ERROR_CRITICAL = 0x00000003,
//The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
Please note that when using WMI, the WMI service must be running. It's running by default, so if you are 100% certain that the user won't stop op disable it, it will always work.
If you need another service (here WMI) to be running, simply set it as a dependant service:
ServiceInstaller.ServicesDependedOn Property
Then Windows will start it, unless user has explicitly disabled it. Well, he/she can also disable your service, so....
I want to get the actual status of the StartUpType. I’m new in
windows-programming and also in using the win32 api. I’m going to
search some tutorials for this themes.
Can you add a method to your class where I can read the actual status of the service please
Here's a new version of the class. The text in Bold is added. I also changed the way the Win32 errors are handled in the new function. You can just throw a Win32Exception with the ErrorCode. This will show an error with a 'readable' output
The QueryServiceConfig returns more than just the startup type. The code can be easily modify to get more info from the service.
SERVICE_BOOT_START = 0x00000000, //A device driver started by the system loader. This value is valid only for driver services.
SERVICE_SYSTEM_START = 0x00000001, //A device driver started by the IoInitSystem function. This value is valid only for driver services.
SERVICE_AUTO_START = 0x00000002, //A service started automatically by the service control manager during system startup.
SERVICE_DEMAND_START = 0x00000003, //A service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED = 0x00000004 //A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED.
}
[Flags]
public enum ServiceControlAccessRights : int
{
SC_MANAGER_CONNECT = 0x0001, //Required to connect to the service control manager.
SC_MANAGER_CREATE_SERVICE = 0x0002, //Required to call the CreateService function to create a service object and add it to the database.
SC_MANAGER_ENUMERATE_SERVICE= 0x0004, //Required to call the EnumServicesStatusEx function to list the services that are in the database.
SC_MANAGER_LOCK = 0x0008, //Required to call the LockServiceDatabase function to acquire a lock on the database.
SC_MANAGER_QUERY_LOCK_STATUS = 0x0010, //Required to call the QueryServiceLockStatus function to retrieve the lock status information for the database
SC_MANAGER_MODIFY_BOOT_CONFIG= 0x0020, //Required to call the NotifyBootConfigStatus function.
SC_MANAGER_ALL_ACCESS = 0xF003F //Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights in this table.
}
[Flags]
public enum ServiceAccessRights : int
{
SERVICE_QUERY_CONFIG = 0x0001, //Required to call the QueryServiceConfig and QueryServiceConfig2 functions to query the service configuration.
SERVICE_CHANGE_CONFIG = 0x0002, //Required to call the ChangeServiceConfig or ChangeServiceConfig2 function to change the service configuration. Because this grants the caller the right to change the executable file that the system runs, it should be granted only to administrators.
SERVICE_QUERY_STATUS = 0x0004, //Required to call the QueryServiceStatusEx function to ask the service control manager about the status of the service.
SERVICE_ENUMERATE_DEPENDENTS = 0x0008, //Required to call the EnumDependentServices function to enumerate all the services dependent on the service.
SERVICE_START = 0x0010, //Required to call the StartService function to start the service.
SERVICE_STOP = 0x0020, //Required to call the ControlService function to stop the service.
SERVICE_PAUSE_CONTINUE = 0x0040, //Required to call the ControlService function to pause or continue the service.
SERVICE_INTERROGATE = 0x0080, //Required to call the ControlService function to ask the service to report its status immediately.
SERVICE_USER_DEFINED_CONTROL = 0x0100, //Required to call the ControlService function to specify a user-defined control code.
SERVICE_ALL_ACCESS = 0xF01FF //Includes STANDARD_RIGHTS_REQUIRED in addition to all access rights in this table.
SERVICE_FILE_SYSTEM_DRIVER = 0x00000002, //File system driver service.
SERVICE_WIN32_OWN_PROCESS = 0x00000010, //Service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS = 0x00000020, //Service that shares a process with other services.
SERVICE_INTERACTIVE_PROCESS = 0x00000100, //The service can interact with the desktop.
SERVICE_NO_CHANGE = 0xffffffff
}
public enum ServiceErrorControl : uint
{
SERVICE_ERROR_IGNORE = 0x00000000, //The startup program ignores the error and continues the startup operation.
SERVICE_ERROR_NORMAL = 0x00000001, //The startup program logs the error in the event log but continues the startup operation.
SERVICE_ERROR_SEVERE = 0x00000002, //SERVICE_ERROR_CRITICAL = 0x00000003, //The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
SERVICE_ERROR_CRITICAL = 0x00000003, //The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
I don't think there is a standard fuction for that in the .net framework, but you can always use interop to access a service. You need to call the following Win32Api methods (use dllimport):
Windows-Service StartUP
BrentNewbury
UPDATE:
There's an error in the QUERY_SERVICE_CONFIG struct I posted earlier. The string members should have the MarshalAs attribute set to UnmanagedType.LPStr instead of UnmanagedType.LPWStr
Here's the new Struct definition (also updated in original post)
public
struct QUERY_SERVICE_CONFIG {}
James_Peters
Ali Chant
Quoyle
Please note that when using WMI, the WMI service must be running. It's running by default, so if you are 100% certain that the user won't stop op disable it, it will always work.
Here's a class you can use to do the same with the Win32 api. Just copy the code below into a class file & use the following code to try it (it will set the startup type of the messenger service to 'Manual'):
ServiceManager.ChangeStartupType("Messenger", ServiceStartupType.SERVICE_DEMAND_START);
using
System;namespace
ServiceDemo{
public enum ServiceStartupType : int
{
SERVICE_BOOT_START = 0x00000000,
//A device driver started by the system loader. This value is valid only for driver services.SERVICE_SYSTEM_START = 0x00000001,
//A device driver started by the IoInitSystem function. This value is valid only for driver services.SERVICE_AUTO_START = 0x00000002,
//A service started automatically by the service control manager during system startup.SERVICE_DEMAND_START = 0x00000003,
//A service started by the service control manager when a process calls the StartService function.SERVICE_DISABLED = 0x00000004
//A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED.}
[Flags]
public enum ServiceControlAccessRights : int {SC_MANAGER_CONNECT = 0x0001,
//Required to connect to the service control manager.SC_MANAGER_CREATE_SERVICE = 0x0002,
//Required to call the CreateService function to create a service object and add it to the database.SC_MANAGER_ENUMERATE_SERVICE= 0x0004,
//Required to call the EnumServicesStatusEx function to list the services that are in the database.SC_MANAGER_LOCK = 0x0008,
//Required to call the LockServiceDatabase function to acquire a lock on the database.SC_MANAGER_QUERY_LOCK_STATUS = 0x0010,
//Required to call the QueryServiceLockStatus function to retrieve the lock status information for the databaseSC_MANAGER_MODIFY_BOOT_CONFIG= 0x0020,
//Required to call the NotifyBootConfigStatus function.SC_MANAGER_ALL_ACCESS = 0xF003F
//Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights in this table.}
[Flags]
public enum ServiceAccessRights : int {SERVICE_QUERY_CONFIG = 0x0001,
//Required to call the QueryServiceConfig and QueryServiceConfig2 functions to query the service configuration.SERVICE_CHANGE_CONFIG = 0x0002,
//Required to call the ChangeServiceConfig or ChangeServiceConfig2 function to change the service configuration. Because this grants the caller the right to change the executable file that the system runs, it should be granted only to administrators.SERVICE_QUERY_STATUS = 0x0004,
//Required to call the QueryServiceStatusEx function to ask the service control manager about the status of the service.SERVICE_ENUMERATE_DEPENDENTS = 0x0008,
//Required to call the EnumDependentServices function to enumerate all the services dependent on the service.SERVICE_START = 0x0010,
//Required to call the StartService function to start the service.SERVICE_STOP = 0x0020,
//Required to call the ControlService function to stop the service.SERVICE_PAUSE_CONTINUE = 0x0040,
//Required to call the ControlService function to pause or continue the service.SERVICE_INTERROGATE = 0x0080,
//Required to call the ControlService function to ask the service to report its status immediately.SERVICE_USER_DEFINED_CONTROL = 0x0100,
//Required to call the ControlService function to specify a user-defined control code.SERVICE_ALL_ACCESS = 0xF01FF
//Includes STANDARD_RIGHTS_REQUIRED in addition to all access rights in this table.}
[Flags]
public enum ServiceType : uint {SERVICE_KERNEL_DRIVER = 0x00000001,
//Driver service.SERVICE_FILE_SYSTEM_DRIVER = 0x00000002,
//File system driver service.SERVICE_WIN32_OWN_PROCESS = 0x00000010,
//Service that runs in its own process.SERVICE_WIN32_SHARE_PROCESS = 0x00000020,
//Service that shares a process with other services.SERVICE_INTERACTIVE_PROCESS = 0x00000100,
//The service can interact with the desktop.SERVICE_NO_CHANGE = 0xffffffff
}
public enum ServiceErrorControl : uint{
SERVICE_ERROR_IGNORE = 0x00000000,
//The startup program ignores the error and continues the startup operation.SERVICE_ERROR_NORMAL = 0x00000001,
//The startup program logs the error in the event log but continues the startup operation.SERVICE_ERROR_SEVERE = 0x00000002,
//SERVICE_ERROR_CRITICAL = 0x00000003, //The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.SERVICE_ERROR_CRITICAL = 0x00000003,
//The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.SERVICE_NO_CHANGE = 0xffffffff
}
public class ServiceManager{
[System.Runtime.InteropServices.DllImport( "kernel32.dll", EntryPoint = "GetLastError" )]
private static extern int GetLastError();[System.Runtime.InteropServices.DllImport( "advapi32.dll", EntryPoint = "OpenSCManager" )]
private static extern int OpenSCManager( string machineName, string databaseName,ServiceControlAccessRights desiredAccess);
[System.Runtime.InteropServices.DllImport( "advapi32.dll", EntryPoint = "CloseServiceHandle" )]
private static extern int CloseServiceHandle( int hSCObject );[System.Runtime.InteropServices.DllImport( "advapi32.dll", EntryPoint = "OpenService" )]
private static extern int OpenService( int hSCManager, string serviceName,ServiceAccessRights desiredAccess);
[System.Runtime.InteropServices.DllImport( "advapi32.dll", EntryPoint = "ChangeServiceConfig" )]
private static extern int ChangeServiceConfig( int hService,ServiceType dwServiceType,
ServiceStartupType dwStartType,
ServiceErrorControl dwErrorControl,
string lpBinaryPathName, string lpLoadOrderGroup,IntPtr lpdwTagId,
string lpDependencies, string lpServiceStartName, string lpPassword, string lpDisplayName );
public ServiceManager(){
// // TODO: Add constructor logic here //}
public static void ChangeStartupType(string serviceName, ServiceStartupType startupType){
//open the service control manager int SCManager = OpenSCManager( null, null,ServiceControlAccessRights.SC_MANAGER_CONNECT);
//verify if the SC is opened if(SCManager == 0){
throw new Exception( string.Format("Unable to open Service Control Manager. GetLastError returned {0}",
GetLastError().ToString()));
}
//open the service int Service = OpenService(SCManager,
serviceName,
ServiceAccessRights.SERVICE_CHANGE_CONFIG);
//verify if the service is opened if(Service == 0){
//get the last dll error before making the next call int LastError = GetLastError(); //make sure the SCManager is closedCloseServiceHandle(SCManager);
throw new Exception( string.Format("Unable to open the requested Service. GetLastError returned {0}",
LastError.ToString()));
}
//try to change the startuptype int ChangeResult = ChangeServiceConfig(Service,
ServiceType.SERVICE_NO_CHANGE,
startupType,
ServiceErrorControl.SERVICE_NO_CHANGE,
null, null,IntPtr.Zero,
null, null, null, null); if(ChangeResult == 0){
//get the last dll error before making the next call int LastError = GetLastError();CloseServiceHandle(SCManager);
CloseServiceHandle(Service);
throw new Exception( string.Format("Unable to change the Service Config. GetLastError returned {0}",
GetLastError().ToString()));
}
//clean upCloseServiceHandle(SCManager);
CloseServiceHandle(Service);
}
}
}
Mike Russo
You can do it with wmi, here is vb.net cdoe:
http://www.xtremevbtalk.com/showthread.php t=259004
CougarDave
Up to now, I dind’t work with Win32Api it would help me if you give me a short code example
Markus
spano
If you need another service (here WMI) to be running, simply set it as a dependant service:
ServiceInstaller.ServicesDependedOn Property
Then Windows will start it, unless user has explicitly disabled it. Well, he/she can also disable your service, so....
TerminalReality
I want to get the actual status of the StartUpType. I’m new in windows-programming and also in using the win32 api. I’m going to search some tutorials for this themes.
Can you add a method to your class where I can read the actual status of the service please
greets markus
JonPL
Hi Markus,
Here's a new version of the class. The text in Bold is added. I also changed the way the Win32 errors are handled in the new function. You can just throw a Win32Exception with the ErrorCode. This will show an error with a 'readable' output
The QueryServiceConfig returns more than just the startup type. The code can be easily modify to get more info from the service.
Use the new function like this:
ServiceStartupType startup = ServiceManager.GetStartupType("Messenger");
The new class;
using
System;using System.Runtime.InteropServices;
namespace
ServiceDemo{
public enum ServiceStartupType : int
{
SERVICE_BOOT_START = 0x00000000, //A device driver started by the system loader. This value is valid only for driver services.
SERVICE_SYSTEM_START = 0x00000001, //A device driver started by the IoInitSystem function. This value is valid only for driver services.
SERVICE_AUTO_START = 0x00000002, //A service started automatically by the service control manager during system startup.
SERVICE_DEMAND_START = 0x00000003, //A service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED = 0x00000004 //A service that cannot be started. Attempts to start the service result in the error code ERROR_SERVICE_DISABLED.
}
[Flags]
public enum ServiceControlAccessRights : int
{
SC_MANAGER_CONNECT = 0x0001, //Required to connect to the service control manager.
SC_MANAGER_CREATE_SERVICE = 0x0002, //Required to call the CreateService function to create a service object and add it to the database.
SC_MANAGER_ENUMERATE_SERVICE= 0x0004, //Required to call the EnumServicesStatusEx function to list the services that are in the database.
SC_MANAGER_LOCK = 0x0008, //Required to call the LockServiceDatabase function to acquire a lock on the database.
SC_MANAGER_QUERY_LOCK_STATUS = 0x0010, //Required to call the QueryServiceLockStatus function to retrieve the lock status information for the database
SC_MANAGER_MODIFY_BOOT_CONFIG= 0x0020, //Required to call the NotifyBootConfigStatus function.
SC_MANAGER_ALL_ACCESS = 0xF003F //Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights in this table.
}
[Flags]
public enum ServiceAccessRights : int
{
SERVICE_QUERY_CONFIG = 0x0001, //Required to call the QueryServiceConfig and QueryServiceConfig2 functions to query the service configuration.
SERVICE_CHANGE_CONFIG = 0x0002, //Required to call the ChangeServiceConfig or ChangeServiceConfig2 function to change the service configuration. Because this grants the caller the right to change the executable file that the system runs, it should be granted only to administrators.
SERVICE_QUERY_STATUS = 0x0004, //Required to call the QueryServiceStatusEx function to ask the service control manager about the status of the service.
SERVICE_ENUMERATE_DEPENDENTS = 0x0008, //Required to call the EnumDependentServices function to enumerate all the services dependent on the service.
SERVICE_START = 0x0010, //Required to call the StartService function to start the service.
SERVICE_STOP = 0x0020, //Required to call the ControlService function to stop the service.
SERVICE_PAUSE_CONTINUE = 0x0040, //Required to call the ControlService function to pause or continue the service.
SERVICE_INTERROGATE = 0x0080, //Required to call the ControlService function to ask the service to report its status immediately.
SERVICE_USER_DEFINED_CONTROL = 0x0100, //Required to call the ControlService function to specify a user-defined control code.
SERVICE_ALL_ACCESS = 0xF01FF //Includes STANDARD_RIGHTS_REQUIRED in addition to all access rights in this table.
}
[Flags]
public enum ServiceType : uint
{
SERVICE_KERNEL_DRIVER = 0x00000001, //Driver service.
SERVICE_FILE_SYSTEM_DRIVER = 0x00000002, //File system driver service.
SERVICE_WIN32_OWN_PROCESS = 0x00000010, //Service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS = 0x00000020, //Service that shares a process with other services.
SERVICE_INTERACTIVE_PROCESS = 0x00000100, //The service can interact with the desktop.
SERVICE_NO_CHANGE = 0xffffffff
}
public enum ServiceErrorControl : uint
{
SERVICE_ERROR_IGNORE = 0x00000000, //The startup program ignores the error and continues the startup operation.
SERVICE_ERROR_NORMAL = 0x00000001, //The startup program logs the error in the event log but continues the startup operation.
SERVICE_ERROR_SEVERE = 0x00000002, //SERVICE_ERROR_CRITICAL = 0x00000003, //The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
SERVICE_ERROR_CRITICAL = 0x00000003, //The startup program logs the error in the event log, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.
SERVICE_NO_CHANGE = 0xffffffff
}
[StructLayout(LayoutKind.Sequential)]
public struct QUERY_SERVICE_CONFIG
{
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwServiceType;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwStartType;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwErrorControl;
[MarshalAs(UnmanagedType.LPStr)]
public String lpBinaryPathName;
[MarshalAs(UnmanagedType.LPStr)]
public String lpLoadOrderGroup;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwTagID;
[MarshalAs(UnmanagedType.LPStr)]
public String lpDependencies;
[MarshalAs(UnmanagedType.LPStr)]
public String lpServiceStartName;
[MarshalAs(UnmanagedType.LPStr)]
public String lpDisplayName;
}
public class ServiceManager
{
[DllImport( "kernel32.dll", EntryPoint = "GetLastError" )]
private static extern int GetLastError();
[DllImport( "advapi32.dll", EntryPoint = "OpenSCManager" )]
private static extern int OpenSCManager(
string machineName,
string databaseName,
ServiceControlAccessRights desiredAccess);
[DllImport( "advapi32.dll", EntryPoint = "CloseServiceHandle" )]
private static extern int CloseServiceHandle( int hSCObject );
[DllImport( "advapi32.dll", EntryPoint = "OpenService" )]
private static extern int OpenService(
int hSCManager,
string serviceName,
ServiceAccessRights desiredAccess);
[DllImport( "advapi32.dll", EntryPoint = "ChangeServiceConfig" )]
private static extern int ChangeServiceConfig(
int hService,
ServiceType dwServiceType,
ServiceStartupType dwStartType,
ServiceErrorControl dwErrorControl,
string lpBinaryPathName,
string lpLoadOrderGroup,
IntPtr lpdwTagId,
string lpDependencies,
string lpServiceStartName,
string lpPassword,
string lpDisplayName );
[DllImport( "advapi32.dll", EntryPoint = "QueryServiceConfig" )]
private static extern int QueryServiceConfig(
int hService,
IntPtr lpServiceConfig,
int cbBufSize,
out int pcbBytesNeeded);
public ServiceManager()
{
//
// TODO: Add constructor logic here
//
}
public static void ChangeStartupType(string serviceName, ServiceStartupType startupType)
{
//open the service control manager
int SCManager = OpenSCManager(
null,
null,
ServiceControlAccessRights.SC_MANAGER_CONNECT);
//verify if the SC is opened
if(SCManager == 0)
{
throw new Exception(
string.Format(
"Unable to open Service Control Manager. GetLastError returned {0}",
GetLastError().ToString()));
}
//open the service
int Service = OpenService(
SCManager,
serviceName,
ServiceAccessRights.SERVICE_CHANGE_CONFIG);
//verify if the service is opened
if(Service == 0)
{
//get the last dll error before making the next call
int LastError = GetLastError();
//make sure the SCManager is closed
CloseServiceHandle(SCManager);
throw new Exception(
string.Format(
"Unable to open the requested Service. GetLastError returned {0}",
LastError.ToString()));
}
//try to change the startuptype
int ChangeResult = ChangeServiceConfig(
Service,
ServiceType.SERVICE_NO_CHANGE,
startupType,
ServiceErrorControl.SERVICE_NO_CHANGE,
null,
null,
IntPtr.Zero,
null,
null,
null,
null);
if(ChangeResult == 0)
{
//get the last dll error before making the next call
int LastError = GetLastError();
CloseServiceHandle(SCManager);
CloseServiceHandle(Service);
throw new Exception(
string.Format(
"Unable to change the Service Config. GetLastError returned {0}",
GetLastError().ToString()));
}
//clean up
CloseServiceHandle(SCManager);
CloseServiceHandle(Service);
}
public static ServiceStartupType GetStartupType(string serviceName)
{
//open the service control manager
int SCManager = OpenSCManager(
null,
null,
ServiceControlAccessRights.SC_MANAGER_CONNECT);
//verify if the SC is opened
if(SCManager == 0)
{
throw new System.ComponentModel.Win32Exception(GetLastError());
}
//open the service
int Service = OpenService(
SCManager,
serviceName,
ServiceAccessRights.SERVICE_QUERY_CONFIG);
//verify if the service is opened
if(Service == 0)
{
//get the last dll error before making the next call
int LastError = GetLastError();
//make sure the SCManager is closed
CloseServiceHandle(SCManager);
throw new System.ComponentModel.Win32Exception(LastError);
}
int dwBytesNeeded = 0;
// Allocate memory for struct.
IntPtr ptr = Marshal.AllocHGlobal(4096);
int QueryResult = QueryServiceConfig(
Service,
ptr,
4096,
out dwBytesNeeded);
if(QueryResult == 0)
{
//get the last dll error before making the next call
int LastError = GetLastError();
CloseServiceHandle(SCManager);
CloseServiceHandle(Service);
throw new System.ComponentModel.Win32Exception(LastError);
}
//clean up
CloseServiceHandle(SCManager);
CloseServiceHandle(Service);
//cast the buffer to a QUERY_SERVICE_CONFIG struct
QUERY_SERVICE_CONFIG config =
(QUERY_SERVICE_CONFIG)Marshal.PtrToStructure(
ptr, typeof(QUERY_SERVICE_CONFIG));
return (ServiceStartupType)config.dwStartType;
}
}
}
Jonathan Allen
I don't think there is a standard fuction for that in the .net framework, but you can always use interop to access a service. You need to call the following Win32Api methods (use dllimport):
1. OpenScManager
2. OpenService
3. ChangeServiceConfig
4. CloseServiceHandle (for the service)
5. CloseServiceHandle (for the ScManager)
All these function are in advapi32.dll.
Let me know if you need more help so I can supply you with a code example.
Sven