hi Vinay,
I'm not sure if there's a .net function for what you need, but i know
for some information about services, you need to resort to win32 calls,
so you might find this helpful. be aware that it was my first time
getting down and dirty with marshalling in c#, but it seems to work fine
for me (except for TagID. i wasn't really sure what it does, so don't
rely on it's value).
HI,
I am writing a utility which will list all the services
running on system like services.msc program. Now I want
to display the Startup type of service like
manual/automation.
How can I get that property? I just want to read that
property, and do not want to create new one.
TIA,
Vinay
public namespace Services
{
/// <summary>
/// Some wrappers around Win32 calls dealing with services.
/// </summary>
public class ServiceConfigurator
{
[StructLayout(LayoutKind.Sequential)]
private struct QueryServiceConfigStruct
{
public int serviceType;
public int startType;
public int errorControl;
public IntPtr binaryPathName;
public IntPtr loadOrderGroup;
public int tagID;
public IntPtr dependencies;
public IntPtr startName;
public IntPtr displayName;
}
public struct ServiceInfo
{
public int serviceType;
public int startType;
public int errorControl;
public string binaryPathName;
public string loadOrderGroup;
public int tagID;
public string dependencies;
public string startName;
public string displayName;
}
#region constants
private enum SCManagerAccess :int
{
GENERIC_ALL = 0x10000000
}
private enum ServiceAccess :int
{
QUERY_CONFIG = 0x1,
CHANGE_CONFIG = 0x2,
}
private const int SERVICE_NO_CHANGE = 0xFFFF;
#endregion
#region DllImports
[DllImport("advapi32.dll",
SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr OpenSCManager(
[MarshalAs(UnmanagedType.LPTStr)]
string machineName,
[MarshalAs(UnmanagedType.LPTStr)]
string databaseName,
int desiredAccess);
[DllImport("advapi32.dll",
SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr OpenService(
IntPtr scManager,
[MarshalAs(UnmanagedType.LPTStr)]
string serviceName,
int desiredAccess);
[DllImport("advapi32.dll",
SetLastError = true, CharSet = CharSet.Auto)]
private static extern int ChangeServiceConfig(
IntPtr service,
int serviceType,
int startType,
int errorControl,
[MarshalAs(UnmanagedType.LPTStr)]
string binaryPathName,
[MarshalAs(UnmanagedType.LPTStr)]
string loadOrderGroup,
IntPtr tagID,
[MarshalAs(UnmanagedType.LPTStr)]
string dependencies,
[MarshalAs(UnmanagedType.LPTStr)]
string startName,
[MarshalAs(UnmanagedType.LPTStr)]
string password,
[MarshalAs(UnmanagedType.LPTStr)]
string displayName);
[DllImport("advapi32.dll",
SetLastError = true, CharSet = CharSet.Auto)]
private static extern int QueryServiceConfig(
IntPtr service,
IntPtr queryServiceConfig,
int bufferSize,
ref int bytesNeeded);
#endregion
public static ServiceInfo GetServiceInfo(string ServiceName)
{
if (ServiceName.Equals(""))
throw new NullReferenceException(
"ServiceName must contain a valid service name.");
IntPtr scManager = OpenSCManager(".", null,
(int)SCManagerAccess.GENERIC_ALL);
if (scManager.ToInt32() <= 0)
throw new Win32Exception();
IntPtr service = OpenService(scManager,
ServiceName, (int) ServiceAccess.QUERY_CONFIG);
if (service.ToInt32() <= 0)
throw new NullReferenceException();
int bytesNeeded = 5;
QueryServiceConfigStruct qscs = new QueryServiceConfigStruct();
IntPtr qscPtr = Marshal.AllocCoTaskMem(0);
int retCode = QueryServiceConfig(service, qscPtr,
0, ref bytesNeeded);
if (retCode == 0 && bytesNeeded == 0)
{
throw new Win32Exception();
}
else
{
qscPtr = Marshal.AllocCoTaskMem(bytesNeeded);
retCode = QueryServiceConfig(service, qscPtr,
bytesNeeded, ref bytesNeeded);
if (retCode == 0)
{
throw new Win32Exception();
}
qscs.binaryPathName = IntPtr.Zero;
qscs.dependencies = IntPtr.Zero;
qscs.displayName = IntPtr.Zero;
qscs.loadOrderGroup = IntPtr.Zero;
qscs.startName = IntPtr.Zero;
qscs = (QueryServiceConfigStruct)
Marshal.PtrToStructure(qscPtr,
new QueryServiceConfigStruct().GetType());
}
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.binaryPathName =
Marshal.PtrToStringAuto(qscs.binaryPathName);
serviceInfo.dependencies =
Marshal.PtrToStringAuto(qscs.dependencies);
serviceInfo.displayName =
Marshal.PtrToStringAuto(qscs.displayName);
serviceInfo.loadOrderGroup =
Marshal.PtrToStringAuto(qscs.loadOrderGroup);
serviceInfo.startName =
Marshal.PtrToStringAuto(qscs.startName);
serviceInfo.errorControl = qscs.errorControl;
serviceInfo.serviceType = qscs.serviceType;
serviceInfo.startType = qscs.startType;
serviceInfo.tagID = qscs.tagID;
Marshal.FreeCoTaskMem(qscPtr);
return serviceInfo;
}
public static void ChangeAccount(string ServiceName,
string Username, string Password)
{
ServiceInfo serviceInfo = GetServiceInfo(ServiceName);
IntPtr scManager = OpenSCManager(".", null,
(int)SCManagerAccess.GENERIC_ALL);
if (scManager.ToInt32() <= 0)
throw new Win32Exception();
IntPtr service = OpenService(scManager,
ServiceName, (int)ServiceAccess.CHANGE_CONFIG);
if (service.ToInt32() <= 0)
throw new Win32Exception();
if (ChangeServiceConfig(service, serviceInfo.serviceType,
serviceInfo.startType, serviceInfo.errorControl,
serviceInfo.binaryPathName, serviceInfo.loadOrderGroup,
IntPtr.Zero, serviceInfo.dependencies,
Username, Password, serviceInfo.displayName) == 0)
{
throw new Win32Exception();
}
}
}
}