mirror of https://github.com/dahall/Vanara.git
Revert "Added some missing functions, structs and enums to winsvc.cs and tests"
This reverts commit dd15c0478c
.
pull/47/head
parent
ee64aca822
commit
8aefdc9389
|
@ -61,13 +61,8 @@ namespace Vanara.InteropServices
|
|||
/// <returns>SafeHGlobalHandle object to an native (unmanaged) Unicode string</returns>
|
||||
public SafeHGlobalHandle(string s) : base(s) { }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeHGlobalHandle"/> class.</summary>
|
||||
/// <param name="structureType">The type of a structure</param>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">size - The value of this argument must be non-negative</exception>
|
||||
public SafeHGlobalHandle(Type structureType) : base(Marshal.SizeOf(structureType)) { }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeHGlobalHandle"/> class.</summary>
|
||||
[ExcludeFromCodeCoverage]
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeHGlobalHandle"/> class.</summary>
|
||||
[ExcludeFromCodeCoverage]
|
||||
internal SafeHGlobalHandle() : base(0) { }
|
||||
|
||||
/// <summary>Represents a NULL memory pointer.</summary>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Vanara.Extensions;
|
||||
|
@ -259,7 +259,7 @@ namespace Vanara.PInvoke
|
|||
|
||||
/// <summary>The current state of the service.</summary>
|
||||
[PInvokeData("winsvc.h", MSDNShortId = "d268609b-d442-4d0f-9d49-ed23fee84961")]
|
||||
public enum ServiceState : uint
|
||||
public enum ServiceState
|
||||
{
|
||||
/// <summary>The service continue is pending.</summary>
|
||||
SERVICE_CONTINUE_PENDING = 0x00000005,
|
||||
|
@ -283,69 +283,9 @@ namespace Vanara.PInvoke
|
|||
SERVICE_STOPPED = 0x00000001,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Service control codes to be used with <see cref="ControlService"/> and <see cref="ControlServiceEx"/>
|
||||
/// </summary>
|
||||
public enum ServiceControl : uint
|
||||
{
|
||||
/// <summary>Notifies a service that it should stop. The hService handle must have the SERVICE_STOP access right. After sending the stop request to a service, you should not send other controls to the service.</summary>
|
||||
SERVICE_CONTROL_STOP = 0x00000001,
|
||||
/// <summary>Notifies a service that it should pause. The hService handle must have the SERVICE_PAUSE_CONTINUE access right.</summary>
|
||||
SERVICE_CONTROL_PAUSE = 0x00000002,
|
||||
/// <summary>Notifies a paused service that it should resume. The hService handle must have the SERVICE_PAUSE_CONTINUE access right.</summary>
|
||||
SERVICE_CONTROL_CONTINUE = 0x00000003,
|
||||
/// <summary>
|
||||
/// Notifies a service that it should report its current status information to the service control manager. The hService handle must have the SERVICE_INTERROGATE access right.
|
||||
/// Note that this control is not generally useful as the SCM is aware of the current state of the service
|
||||
/// </summary>
|
||||
SERVICE_CONTROL_INTERROGATE = 0x00000004,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_SHUTDOWN = 0x00000005,
|
||||
/// <summary>Notifies a service that its startup parameters have changed. The hService handle must have the SERVICE_PAUSE_CONTINUE access right.</summary>
|
||||
SERVICE_CONTROL_PARAMCHANGE = 0x00000006,
|
||||
/// <summary>Notifies a network service that there is a new component for binding. The hService handle must have the SERVICE_PAUSE_CONTINUE access right. However, this control code has been deprecated; use Plug and Play functionality instead.</summary>
|
||||
SERVICE_CONTROL_NETBINDADD = 0x00000007,
|
||||
/// <summary>Notifies a network service that a component for binding has been removed. The hService handle must have the SERVICE_PAUSE_CONTINUE access right. However, this control code has been deprecated; use Plug and Play functionality instead.</summary>
|
||||
SERVICE_CONTROL_NETBINDREMOVE = 0x00000008,
|
||||
/// <summary>Notifies a network service that a disabled binding has been enabled. The hService handle must have the SERVICE_PAUSE_CONTINUE access right. However, this control code has been deprecated; use Plug and Play functionality instead.</summary>
|
||||
SERVICE_CONTROL_NETBINDENABLE = 0x00000009,
|
||||
/// <summary>Notifies a network service that one of its bindings has been disabled. The hService handle must have the SERVICE_PAUSE_CONTINUE access right. However, this control code has been deprecated; use Plug and Play functionality instead.</summary>
|
||||
SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_DEVICEEVENT = 0x0000000B,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_POWEREVENT = 0x0000000D,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_PRESHUTDOWN = 0x0000000F,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_TIMECHANGE = 0x00000010,
|
||||
//#define SERVICE_CONTROL_USER_LOGOFF = 0x00000011
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_TRIGGEREVENT = 0x00000020,
|
||||
//reserved for internal use = 0x00000021
|
||||
//reserved for internal use = 0x00000050
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_LOWRESOURCES = 0x00000060,
|
||||
/// <summary></summary>
|
||||
SERVICE_CONTROL_SYSTEMLOWRESOURCES = 0x00000061
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info levels for <see cref="ControlServiceEx"/>
|
||||
/// </summary>
|
||||
public enum ServiceInfoLevels : uint
|
||||
{
|
||||
[CorrespondingType(typeof(SERVICE_CONTROL_STATUS_REASON_PARAMS))]
|
||||
SERVICE_CONTROL_STATUS_REASON_INFO = 1
|
||||
}
|
||||
|
||||
/// <summary>Service trigger action types referenced by <see cref="SERVICE_TRIGGER"/>.</summary>
|
||||
[PInvokeData("winsvc.h", MSDNShortId = "a57aa702-40a2-4880-80db-6c4f43c3e7ea")]
|
||||
public enum ServiceTriggerAction : uint
|
||||
/// <summary>Service trigger action types referenced by <see cref="SERVICE_TRIGGER"/>.</summary>
|
||||
[PInvokeData("winsvc.h", MSDNShortId = "a57aa702-40a2-4880-80db-6c4f43c3e7ea")]
|
||||
public enum ServiceTriggerAction
|
||||
{
|
||||
/// <summary>Start the service when the specified trigger event occurs.</summary>
|
||||
SERVICE_TRIGGER_ACTION_SERVICE_START = 1,
|
||||
|
@ -1196,7 +1136,7 @@ namespace Vanara.PInvoke
|
|||
// lpMachineName, LPCSTR lpDatabaseName, DWORD dwDesiredAccess );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[PInvokeData("winsvc.h", MSDNShortId = "a0237989-e5a7-4a3a-ab23-e2474a995341")]
|
||||
public static extern SafeSC_HANDLE OpenSCManager(string lpMachineName, string lpDatabaseName, ScManagerAccessTypes dwDesiredAccess);
|
||||
public static extern SafeSC_HANDLE OpenSCManager(string lpMachineName, string lpDatabaseName, uint dwDesiredAccess);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Opens an existing service.</para>
|
||||
|
@ -1267,7 +1207,7 @@ namespace Vanara.PInvoke
|
|||
// LPCSTR lpServiceName, DWORD dwDesiredAccess );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[PInvokeData("winsvc.h", MSDNShortId = "e0a42613-95ad-4d0f-a464-c6df33014064")]
|
||||
public static extern SafeSC_HANDLE OpenService(SC_HANDLE hSCManager, string lpServiceName, ServiceAccessTypes dwDesiredAccess);
|
||||
public static extern SafeSC_HANDLE OpenService(SC_HANDLE hSCManager, string lpServiceName, uint dwDesiredAccess);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the configuration parameters of the specified service. Optional configuration parameters are available using the
|
||||
|
@ -1470,53 +1410,6 @@ namespace Vanara.PInvoke
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the current status of the specified service based on the specified information level.
|
||||
/// </summary>
|
||||
/// <param name="hService">
|
||||
/// A handle to the service. This handle is returned by the <see cref="CreateService"/> or <see cref="OpenService"/> function, and it must have the <see cref="ServiceAccessTypes.SERVICE_QUERY_STATUS"/> access right.
|
||||
/// For more information, see <see cref="https://docs.microsoft.com/en-gb/windows/desktop/Services/service-security-and-access-rights">Service Security and Access Rights.</see>
|
||||
/// </param>
|
||||
/// <param name="InfoLevel">The service attributes to be returned. Use <see cref="ServiceStatusType.SC_STATUS_PROCESS_INFO"/> to retrieve the service status information. The lpBuffer parameter is a pointer to a <see cref="SERVICE_STATUS_PROCESS" /> structure. Currently, no other information levels are defined.</param>
|
||||
/// <param name="lpBuffer"></param>
|
||||
/// <param name="cbBufSize"></param>
|
||||
/// <param name="pcbBytesNeeded"></param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
|
||||
/// information, call GetLastError.
|
||||
/// </returns>
|
||||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[PInvokeData("winsvc.h")]
|
||||
public static extern bool QueryServiceStatusEx(SC_HANDLE hService, ServiceStatusType InfoLevel, IntPtr lpBuffer, uint cbBufSize, out uint pcbBytesNeeded);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the current status of the specified service based on the specified information level.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="hService">
|
||||
/// A handle to the service. This handle is returned by the <see cref="CreateService"/> or <see cref="OpenService"/> function, and it must have the <see cref="ServiceAccessTypes.SERVICE_QUERY_STATUS"/> access right.
|
||||
/// For more information, see <see cref="https://docs.microsoft.com/en-gb/windows/desktop/Services/service-security-and-access-rights">Service Security and Access Rights.</see>
|
||||
/// </param>
|
||||
/// <param name="InfoLevel">The service attributes to be returned. Use <see cref="ServiceStatusType.SC_STATUS_PROCESS_INFO"/> to retrieve the service status information. The lpBuffer parameter is a pointer to a <see cref="SERVICE_STATUS_PROCESS" /> structure. Currently, no other information levels are defined.</param>
|
||||
/// <param name="statusInfo">A variable that receives the service status information. The format of this data depends on the value of the dwInfoLevel parameter.</param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error
|
||||
/// information, call GetLastError.
|
||||
/// </returns>
|
||||
public static bool QueryServiceStatusEx<T>(SC_HANDLE hService, ServiceStatusType dwInfoLevel, out T statusInfo)
|
||||
{
|
||||
if (!CorrespondingTypeAttribute.CanGet(dwInfoLevel, typeof(T))) throw new ArgumentException("Type mismatch", nameof(statusInfo));
|
||||
var b = QueryServiceStatusEx(hService, dwInfoLevel, IntPtr.Zero, 0, out var size);
|
||||
statusInfo = default;
|
||||
if (!b && Win32Error.GetLastError() != Win32Error.ERROR_INSUFFICIENT_BUFFER) return false;
|
||||
using (var buf = new SafeHGlobalHandle((int)size))
|
||||
{
|
||||
if (!QueryServiceStatusEx(hService, dwInfoLevel, (IntPtr)buf, size, out size)) return false;
|
||||
statusInfo = buf.ToStructure<T>();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Registers a function to handle service control requests.</para>
|
||||
/// <para>
|
||||
|
@ -1754,92 +1647,8 @@ namespace Vanara.PInvoke
|
|||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, in SERVICE_STATUS lpServiceStatus);
|
||||
|
||||
/// <summary>
|
||||
/// Starts a service
|
||||
/// </summary>
|
||||
/// <param name="hServiceStatus">A handle to the service. This handle is returned by the <see cref="OpenService"/> or <see cref="CreateService"/> function, and it must have the <see cref="ServiceAccessTypes.SERVICE_START"/> access right.</param>
|
||||
/// <param name="dwNumServiceArgs">The number of strings in the lpServiceArgVectors array. If lpServiceArgVectors is NULL, this parameter can be zero.</param>
|
||||
/// <param name="lpServiceArgVectors">The null-terminated strings to be passed to the ServiceMain function for the service as arguments. If there are no arguments, this parameter can be NULL. Otherwise, the first argument (lpServiceArgVectors[0]) is the name of the service, followed by any additional arguments (lpServiceArgVectors[1] through lpServiceArgVectors[dwNumServiceArgs-1]).</param>
|
||||
/// <returns>If the function succeeds, the return value is true. If the function fails, the return value is false. To get extended error information, call GetLastError.</returns>
|
||||
/// https://docs.microsoft.com/en-gb/windows/desktop/api/winsvc/nf-winsvc-startservicew
|
||||
[DllImport(Lib.AdvApi32, SetLastError = true)]
|
||||
[PInvokeData("winsvc.h")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool StartService(SC_HANDLE hServiceStatus, int dwNumServiceArgs = 0, string[] lpServiceArgVectors = null);
|
||||
|
||||
/// <summary>
|
||||
/// Marks the specified service for deletion from the service control manager database
|
||||
/// </summary>
|
||||
/// <param name="hServiceStatus">A handle to the service. This handle is returned by the <see cref="OpenService"/> or <see cref="CreateService"/> function, and it must have the <see cref="ACCESS_MASK.DELETE"/> access right.</param>
|
||||
/// <returns>If the function succeeds, the return value is true. If the function fails, the return value is false. To get extended error information, call GetLastError.</returns>
|
||||
/// https://docs.microsoft.com/en-gb/windows/desktop/api/winsvc/nf-winsvc-deleteservice
|
||||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
|
||||
[PInvokeData("winsvc.h")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool DeleteService(SC_HANDLE hServiceStatus);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a control code to a service.
|
||||
/// </summary>
|
||||
/// <param name="hService">A handle to the service. This handle is returned by the <see cref="OpenService"/> or <see cref="CreateService"/> function. The access rights required for this handle depend on the dwControl code requested.</param>
|
||||
/// <param name="dwControl">The <see cref="ServiceControl"/> code to send to the service</param>
|
||||
/// <param name="lpServiceStatus">A pointer to a <see cref="SERVICE_STATUS"/> structure that receives the latest service status information. The information returned reflects the most recent status that the service reported to the service control manager.</param>
|
||||
/// <returns>If the function succeeds, the return value is true. If the function fails, the return value is false. To get extended error information, call GetLastError.</returns>
|
||||
/// https://docs.microsoft.com/en-gb/windows/desktop/api/winsvc/nf-winsvc-controlservice
|
||||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[PInvokeData("winsvc.h")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ControlService(SC_HANDLE hService, ServiceControl dwControl, ref SERVICE_STATUS lpServiceStatus);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a control code to a service
|
||||
/// </summary>
|
||||
/// <param name="hService">A handle to the service. This handle is returned by the <see cref="OpenService"/> or <see cref="CreateService"/> function. The access rights required for this handle depend on the <paramref name="dwControl"/> code requested.</param>
|
||||
/// <param name="dwControl">The <see cref="ServiceControl"/> code to send to the service</param>
|
||||
/// <param name="dwInfoLevel">The information level for the service control parameters. This parameter must be set to <see cref="SERVICE_CONTROL_STATUS_REASON_INFO"/></param>
|
||||
/// <param name="pControlParams">A pointer to the service control parameters. If <paramref name="dwInfoLevel"/> is <see cref="SERVICE_CONTROL_STATUS_REASON_INFO"/>, this member is a pointer to a SERVICE_CONTROL_STATUS_REASON_PARAMS structure.</param>
|
||||
/// <returns>If the function succeeds, the return value is true. If the function fails, the return value is false. To get extended error information, call GetLastError.</returns>
|
||||
/// https://docs.microsoft.com/en-gb/windows/desktop/api/winsvc/nf-winsvc-controlserviceexw
|
||||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[PInvokeData("winsvc.h")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ControlServiceEx(SC_HANDLE hService, ServiceControl dwControl, ServiceInfoLevels dwInfoLevel, [In, Out] ref SERVICE_CONTROL_STATUS_REASON_PARAMS pControlParams);
|
||||
|
||||
/// <summary>
|
||||
/// Stops a service using <see cref="ControlService"/> with <see cref="ServiceControl.SERVICE_CONTROL_STOP"/>
|
||||
/// </summary>
|
||||
/// <param name="hService">A handle to the service. This handle is returned by the <see cref="OpenService"/> or <see cref="CreateService"/> function. The access rights required for this handle depend on the <paramref name="dwControl"/> code requested.</param>
|
||||
/// <returns></returns>
|
||||
public static bool StopService(SC_HANDLE hService)
|
||||
{
|
||||
var lpServiceStatus = new SERVICE_STATUS();
|
||||
return StopService(hService, ref lpServiceStatus);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a service using <see cref="ControlService"/> with <see cref="ServiceControl.SERVICE_CONTROL_STOP"/>
|
||||
/// </summary>
|
||||
/// <param name="hService">A handle to the service. This handle is returned by the <see cref="OpenService"/> or <see cref="CreateService"/> function. The access rights required for this handle depend on the <paramref name="dwControl"/> code requested.</param>
|
||||
/// <param name="lpServiceStatus">A pointer to a <see cref="SERVICE_STATUS"/> structure that receives the latest service status information. The information returned reflects the most recent status that the service reported to the service control manager.</param>
|
||||
/// <returns></returns>
|
||||
public static bool StopService(SC_HANDLE hService, ref SERVICE_STATUS lpServiceStatus)
|
||||
{
|
||||
return ControlService(hService, ServiceControl.SERVICE_CONTROL_STOP, ref lpServiceStatus);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a service using <see cref="ControlServiceEx"/> with <see cref="ServiceControl.SERVICE_CONTROL_STOP"/>
|
||||
/// </summary>
|
||||
/// <param name="hService">A handle to the service. This handle is returned by the <see cref="OpenService"/> or <see cref="CreateService"/> function. The access rights required for this handle depend on the <paramref name="dwControl"/> code requested.</param>
|
||||
/// <param name="reason">A reason and comment for why the service is being stopped</param>
|
||||
/// <returns></returns>
|
||||
public static bool StopService(SC_HANDLE hService, ref SERVICE_CONTROL_STATUS_REASON_PARAMS reason)
|
||||
{
|
||||
return ControlServiceEx(hService, ServiceControl.SERVICE_CONTROL_STOP, ServiceInfoLevels.SERVICE_CONTROL_STATUS_REASON_INFO, ref reason);
|
||||
}
|
||||
|
||||
/// <summary>Contains configuration information for an installed service. It is used by the QueryServiceConfig function.</summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
/// <summary>Contains configuration information for an installed service. It is used by the QueryServiceConfig function.</summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
[PInvokeData("Winsvc.h", MSDNShortId = "ms684950")]
|
||||
public struct QUERY_SERVICE_CONFIG
|
||||
{
|
||||
|
@ -1920,15 +1729,15 @@ namespace Vanara.PInvoke
|
|||
public IEnumerable<string> Dependencies => lpDependencies.ToStringEnum();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Represents an action that the service control manager can perform.</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This structure is used by the <see cref="ChangeServiceConfig2"/> and <see cref="QueryServiceConfig2"/> functions, in the SERVICE_FAILURE_ACTIONS structure.</para>
|
||||
/// </remarks>
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/ns-winsvc-_sc_action typedef struct _SC_ACTION { SC_ACTION_TYPE Type;
|
||||
// DWORD Delay; } SC_ACTION, *LPSC_ACTION;
|
||||
[PInvokeData("winsvc.h", MSDNShortId = "e2c355a6-affe-46bf-a3e6-f8c420422d46")]
|
||||
/// <summary>
|
||||
/// <para>Represents an action that the service control manager can perform.</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This structure is used by the ChangeServiceConfig2 and QueryServiceConfig2 functions, in the SERVICE_FAILURE_ACTIONS structure.</para>
|
||||
/// </remarks>
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/ns-winsvc-_sc_action typedef struct _SC_ACTION { SC_ACTION_TYPE Type;
|
||||
// DWORD Delay; } SC_ACTION, *LPSC_ACTION;
|
||||
[PInvokeData("winsvc.h", MSDNShortId = "e2c355a6-affe-46bf-a3e6-f8c420422d46")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SC_ACTION
|
||||
{
|
||||
|
@ -2652,280 +2461,8 @@ namespace Vanara.PInvoke
|
|||
public uint dwWaitHint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Contains status information for a service. The ControlService, EnumDependentServices, EnumServicesStatus, and QueryServiceStatus
|
||||
/// functions use this structure. A service uses this structure in the SetServiceStatus function to report its current status to the
|
||||
/// service control manager.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
// https://docs.microsoft.com/en-gb/windows/desktop/api/winsvc/ns-winsvc-_service_status_process typedef struct _SERVICE_STATUS_PROCESS {
|
||||
// DWORD dwServiceType; DWORD dwCurrentState; DWORD dwControlsAccepted; DWORD dwWin32ExitCode; DWORD dwServiceSpecificExitCode;
|
||||
// DWORD dwCheckPoint; DWORD dwWaitHint; DWORD dwProcessId; DWORD dwServiceFlags; } SERVICE_STATUS_PROCESS, * LPSERVICE_STATUS_PROCESS;
|
||||
[PInvokeData("winsvc.h")]
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public struct SERVICE_STATUS_PROCESS
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>The type of service. This member can be one of the following values.</para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Value</term>
|
||||
/// <term>Meaning</term>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>SERVICE_FILE_SYSTEM_DRIVER 0x00000002</term>
|
||||
/// <term>The service is a file system driver.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_KERNEL_DRIVER 0x00000001</term>
|
||||
/// <term>The service is a device driver.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_WIN32_OWN_PROCESS 0x00000010</term>
|
||||
/// <term>The service runs in its own process.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_WIN32_SHARE_PROCESS 0x00000020</term>
|
||||
/// <term>The service shares a process with other services.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_USER_OWN_PROCESS 0x00000050</term>
|
||||
/// <term>The service runs in its own process under the logged-on user account.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_USER_SHARE_PROCESS 0x00000060</term>
|
||||
/// <term>The service shares a process with one or more other services that run under the logged-on user account.</term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para>
|
||||
/// If the service type is either SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, and the service is running in the
|
||||
/// context of the LocalSystem account, the following type may also be specified.
|
||||
/// </para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Value</term>
|
||||
/// <term>Meaning</term>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>SERVICE_INTERACTIVE_PROCESS 0x00000100</term>
|
||||
/// <term>The service can interact with the desktop. For more information, see Interactive Services.</term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public ServiceTypes dwServiceType;
|
||||
|
||||
/// <summary>
|
||||
/// <para>The current state of the service. This member can be one of the following values.</para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Value</term>
|
||||
/// <term>Meaning</term>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>SERVICE_CONTINUE_PENDING 0x00000005</term>
|
||||
/// <term>The service continue is pending.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_PAUSE_PENDING 0x00000006</term>
|
||||
/// <term>The service pause is pending.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_PAUSED 0x00000007</term>
|
||||
/// <term>The service is paused.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_RUNNING 0x00000004</term>
|
||||
/// <term>The service is running.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_START_PENDING 0x00000002</term>
|
||||
/// <term>The service is starting.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_STOP_PENDING 0x00000003</term>
|
||||
/// <term>The service is stopping.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_STOPPED 0x00000001</term>
|
||||
/// <term>The service is not running.</term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public ServiceState dwCurrentState;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// The control codes the service accepts and processes in its handler function (see Handler and HandlerEx). A user interface
|
||||
/// process can control a service by specifying a control command in the ControlService or ControlServiceEx function. By default,
|
||||
/// all services accept the <c>SERVICE_CONTROL_INTERROGATE</c> value.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// To accept the <c>SERVICE_CONTROL_DEVICEEVENT</c> value, the service must register to receive device events by using the
|
||||
/// RegisterDeviceNotification function.
|
||||
/// </para>
|
||||
/// <para>The following are the control codes.</para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Control code</term>
|
||||
/// <term>Meaning</term>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_NETBINDCHANGE 0x00000010</term>
|
||||
/// <term>
|
||||
/// The service is a network component that can accept changes in its binding without being stopped and restarted. This control
|
||||
/// code allows the service to receive SERVICE_CONTROL_NETBINDADD, SERVICE_CONTROL_NETBINDREMOVE, SERVICE_CONTROL_NETBINDENABLE,
|
||||
/// and SERVICE_CONTROL_NETBINDDISABLE notifications.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_PARAMCHANGE 0x00000008</term>
|
||||
/// <term>
|
||||
/// The service can reread its startup parameters without being stopped and restarted. This control code allows the service to
|
||||
/// receive SERVICE_CONTROL_PARAMCHANGE notifications.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_PAUSE_CONTINUE 0x00000002</term>
|
||||
/// <term>
|
||||
/// The service can be paused and continued. This control code allows the service to receive SERVICE_CONTROL_PAUSE and
|
||||
/// SERVICE_CONTROL_CONTINUE notifications.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_PRESHUTDOWN 0x00000100</term>
|
||||
/// <term>
|
||||
/// The service can perform preshutdown tasks. This control code enables the service to receive SERVICE_CONTROL_PRESHUTDOWN
|
||||
/// notifications. Note that ControlService and ControlServiceEx cannot send this notification; only the system can send it.
|
||||
/// Windows Server 2003 and Windows XP: This value is not supported.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_SHUTDOWN 0x00000004</term>
|
||||
/// <term>
|
||||
/// The service is notified when system shutdown occurs. This control code allows the service to receive SERVICE_CONTROL_SHUTDOWN
|
||||
/// notifications. Note that ControlService and ControlServiceEx cannot send this notification; only the system can send it.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_STOP 0x00000001</term>
|
||||
/// <term>The service can be stopped. This control code allows the service to receive SERVICE_CONTROL_STOP notifications.</term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para>
|
||||
/// This member can also contain the following extended control codes, which are supported only by HandlerEx. (Note that these
|
||||
/// control codes cannot be sent by ControlService or ControlServiceEx.)
|
||||
/// </para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Control code</term>
|
||||
/// <term>Meaning</term>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_HARDWAREPROFILECHANGE 0x00000020</term>
|
||||
/// <term>
|
||||
/// The service is notified when the computer's hardware profile has changed. This enables the system to send
|
||||
/// SERVICE_CONTROL_HARDWAREPROFILECHANGE notifications to the service.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_POWEREVENT 0x00000040</term>
|
||||
/// <term>
|
||||
/// The service is notified when the computer's power status has changed. This enables the system to send
|
||||
/// SERVICE_CONTROL_POWEREVENT notifications to the service.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_SESSIONCHANGE 0x00000080</term>
|
||||
/// <term>
|
||||
/// The service is notified when the computer's session status has changed. This enables the system to send
|
||||
/// SERVICE_CONTROL_SESSIONCHANGE notifications to the service.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_TIMECHANGE 0x00000200</term>
|
||||
/// <term>
|
||||
/// The service is notified when the system time has changed. This enables the system to send SERVICE_CONTROL_TIMECHANGE
|
||||
/// notifications to the service. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This control code is
|
||||
/// not supported.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_TRIGGEREVENT 0x00000400</term>
|
||||
/// <term>
|
||||
/// The service is notified when an event for which the service has registered occurs. This enables the system to send
|
||||
/// SERVICE_CONTROL_TRIGGEREVENT notifications to the service. Windows Server 2008, Windows Vista, Windows Server 2003 and
|
||||
/// Windows XP: This control code is not supported.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>SERVICE_ACCEPT_USERMODEREBOOT 0x00000800</term>
|
||||
/// <term>
|
||||
/// The services is notified when the user initiates a reboot. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows
|
||||
/// Vista, Windows Server 2003 and Windows XP: This control code is not supported.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public ServiceAcceptedControlCodes dwControlsAccepted;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// The error code the service uses to report an error that occurs when it is starting or stopping. To return an error code
|
||||
/// specific to the service, the service must set this value to <c>ERROR_SERVICE_SPECIFIC_ERROR</c> to indicate that the
|
||||
/// <c>dwServiceSpecificExitCode</c> member contains the error code. The service should set this value to <c>NO_ERROR</c> when it
|
||||
/// is running and on normal termination.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public uint dwWin32ExitCode;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// A service-specific error code that the service returns when an error occurs while the service is starting or stopping. This
|
||||
/// value is ignored unless the <c>dwWin32ExitCode</c> member is set to <c>ERROR_SERVICE_SPECIFIC_ERROR</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public uint dwServiceSpecificExitCode;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// The check-point value the service increments periodically to report its progress during a lengthy start, stop, pause, or
|
||||
/// continue operation. For example, the service should increment this value as it completes each step of its initialization when
|
||||
/// it is starting up. The user interface program that invoked the operation on the service uses this value to track the progress
|
||||
/// of the service during a lengthy operation. This value is not valid and should be zero when the service does not have a start,
|
||||
/// stop, pause, or continue operation pending.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public uint dwCheckPoint;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// The estimated time required for a pending start, stop, pause, or continue operation, in milliseconds. Before the specified
|
||||
/// amount of time has elapsed, the service should make its next call to the SetServiceStatus function with either an incremented
|
||||
/// <c>dwCheckPoint</c> value or a change in <c>dwCurrentState</c>. If the amount of time specified by <c>dwWaitHint</c> passes,
|
||||
/// and <c>dwCheckPoint</c> has not been incremented or <c>dwCurrentState</c> has not changed, the service control manager or
|
||||
/// service control program can assume that an error has occurred and the service should be stopped. However, if the service
|
||||
/// shares a process with other services, the service control manager cannot terminate the service application because it would
|
||||
/// have to terminate the other services sharing the process as well.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public uint dwWaitHint;
|
||||
|
||||
/// <summary>
|
||||
/// The process identifier of the service.
|
||||
/// </summary>
|
||||
public uint dwProcessId;
|
||||
|
||||
/// <summary>
|
||||
/// This member can be one of the following values.
|
||||
/// 0 = The service is running in a process that is not a system process, or it is not running. If the service is running in a process that is not a system process, dwProcessId is nonzero.If the service is not running, dwProcessId is zero.
|
||||
/// 1 = SERVICE_RUNS_IN_SYSTEM_PROCESS The service runs in a system process that must always be running.
|
||||
/// </summary>
|
||||
public uint dwServiceFlags;
|
||||
}
|
||||
|
||||
/// <summary>Provides a handle to a service status handle.</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
/// <summary>Provides a handle to a service status handle.</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SERVICE_STATUS_HANDLE : IHandle
|
||||
{
|
||||
private IntPtr handle;
|
||||
|
@ -3364,163 +2901,7 @@ namespace Vanara.PInvoke
|
|||
protected override bool InternalReleaseHandle() => CloseServiceHandle(this);
|
||||
}
|
||||
|
||||
/// <summary>Service Control Manager object specific access types</summary>
|
||||
/// <see cref="https://docs.microsoft.com/en-gb/windows/desktop/Services/service-security-and-access-rights#access-rights-for-the-service-control-manager"/>
|
||||
[PInvokeData("winsvc.h")]
|
||||
[Flags]
|
||||
public enum ScManagerAccessTypes : uint
|
||||
{
|
||||
/// <summary>Required to connect to the service control manager.</summary>
|
||||
SC_MANAGER_CONNECT = 0x0001,
|
||||
/// <summary>Required to call the CreateService function to create a service object and add it to the database.</summary>
|
||||
SC_MANAGER_CREATE_SERVICE = 0x0002,
|
||||
/// <summary>
|
||||
/// Required to call the <see cref="EnumServicesStatus"/> or <see cref="EnumServicesStatusEx"/> function to list the services that are in the database.
|
||||
/// Required to call the <see cref="NotifyServiceStatusChange"/> function to receive notification when any service is created or deleted.
|
||||
/// </summary>
|
||||
SC_MANAGER_ENUMERATE_SERVICE = 0x0004,
|
||||
/// <summary>Required to call the <see cref="LockServiceDatabase"/> function to acquire a lock on the database.</summary>
|
||||
SC_MANAGER_LOCK = 0x0008,
|
||||
/// <summary>Required to call the <see cref="QueryServiceLockStatus"/> function to retrieve the lock status information for the database.</summary>
|
||||
SC_MANAGER_QUERY_LOCK_STATUS = 0x0010,
|
||||
/// <summary>Required to call the <see cref="NotifyBootConfigStatus"/> function.</summary>
|
||||
SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020,
|
||||
|
||||
/// <summary>Includes <see cref="ACCESS_MASK.STANDARD_RIGHTS_REQUIRED"/>, in addition to all access rights in this table.</summary>
|
||||
SC_MANAGER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
|
||||
SC_MANAGER_CONNECT |
|
||||
SC_MANAGER_CREATE_SERVICE |
|
||||
SC_MANAGER_ENUMERATE_SERVICE |
|
||||
SC_MANAGER_LOCK |
|
||||
SC_MANAGER_QUERY_LOCK_STATUS |
|
||||
SC_MANAGER_MODIFY_BOOT_CONFIG
|
||||
}
|
||||
|
||||
/// <summary>Service object specific access type</summary>
|
||||
/// <see cref="https://docs.microsoft.com/en-gb/windows/desktop/Services/service-security-and-access-rights#access-rights-for-a-service"/>
|
||||
[PInvokeData("winsvc.h")]
|
||||
[Flags]
|
||||
public enum ServiceAccessTypes : uint
|
||||
{
|
||||
/// <summary>Required to call the <see cref="QueryServiceConfig"/> and <see cref="QueryServiceConfig2"/> functions to query the service configuration.</summary>
|
||||
SERVICE_QUERY_CONFIG = 0x0001,
|
||||
/// <summary>Required to call the <see cref="ChangeServiceConfig"/> or <see cref="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.</summary>
|
||||
SERVICE_CHANGE_CONFIG = 0x0002,
|
||||
/// <summary>
|
||||
/// Required to call the <see cref="QueryServiceStatus"/> or <see cref="QueryServiceStatusEx"/> function to ask the service control manager about the status of the service.
|
||||
/// Required to call the <see cref="NotifyServiceStatusChange"/> function to receive notification when a service changes status.
|
||||
/// </summary>
|
||||
SERVICE_QUERY_STATUS = 0x0004,
|
||||
/// <summary>
|
||||
/// Required to call the <see cref="EnumDependentServices"/> function to enumerate all the services dependent on the service.
|
||||
/// </summary>
|
||||
SERVICE_ENUMERATE_DEPENDENTS = 0x0008,
|
||||
/// <summary>Required to call the <see cref="StartService"/> function to start the service.</summary>
|
||||
SERVICE_START = 0x0010,
|
||||
/// <summary>Required to call the <see cref="ControlService"/> function to stop the service.</summary>
|
||||
SERVICE_STOP = 0x0020,
|
||||
/// <summary>Required to call the <see cref="ControlService"/> function to pause or continue the service.</summary>
|
||||
SERVICE_PAUSE_CONTINUE = 0x0040,
|
||||
/// <summary>Required to call the <see cref="ControlService"/> function to ask the service to report its status immediately.</summary>
|
||||
SERVICE_INTERROGATE = 0x0080,
|
||||
/// <summary>Required to call the <see cref="ControlService"/> function to specify a user-defined control code.</summary>
|
||||
SERVICE_USER_DEFINED_CONTROL = 0x0100,
|
||||
|
||||
/// <summary>Includes <see cref="ACCESS_MASK.STANDARD_RIGHTS_REQUIRED"/> in addition to all access rights in this table.</summary>
|
||||
SERVICE_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
|
||||
SERVICE_QUERY_CONFIG |
|
||||
SERVICE_CHANGE_CONFIG |
|
||||
SERVICE_QUERY_STATUS |
|
||||
SERVICE_ENUMERATE_DEPENDENTS |
|
||||
SERVICE_START |
|
||||
SERVICE_STOP |
|
||||
SERVICE_PAUSE_CONTINUE |
|
||||
SERVICE_INTERROGATE |
|
||||
SERVICE_USER_DEFINED_CONTROL
|
||||
}
|
||||
|
||||
/// <summary>Info levels for <see cref="QueryServiceStatusEx"/></summary>
|
||||
public enum ServiceStatusType
|
||||
{
|
||||
[CorrespondingType(typeof(SERVICE_STATUS_PROCESS))]
|
||||
SC_STATUS_PROCESS_INFO = 0
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Service control status reason parameters returned by <see cref="ControlServiceEx"/>
|
||||
/// </summary>
|
||||
[PInvokeData("winsvc.h")]
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public struct SERVICE_CONTROL_STATUS_REASON_PARAMS
|
||||
{
|
||||
public SERVICE_STOP_REASON dwReason;
|
||||
public string pszComment;
|
||||
public SERVICE_STATUS_PROCESS serviceStatus;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SERVICE_STOP_REASON : uint
|
||||
{
|
||||
//
|
||||
// Stop reason flags. Update SERVICE_STOP_REASON_FLAG_MAX when
|
||||
// new flags are added.
|
||||
//
|
||||
SERVICE_STOP_REASON_FLAG_MIN = 0x00000000,
|
||||
SERVICE_STOP_REASON_FLAG_UNPLANNED = 0x10000000,
|
||||
SERVICE_STOP_REASON_FLAG_CUSTOM = 0x20000000,
|
||||
SERVICE_STOP_REASON_FLAG_PLANNED = 0x40000000,
|
||||
SERVICE_STOP_REASON_FLAG_MAX = 0x80000000,
|
||||
|
||||
//
|
||||
// Microsoft major reasons. Update SERVICE_STOP_REASON_MAJOR_MAX when
|
||||
// new codes are added.
|
||||
//
|
||||
SERVICE_STOP_REASON_MAJOR_MIN = 0x00000000,
|
||||
SERVICE_STOP_REASON_MAJOR_OTHER = 0x00010000,
|
||||
SERVICE_STOP_REASON_MAJOR_HARDWARE = 0x00020000,
|
||||
SERVICE_STOP_REASON_MAJOR_OPERATINGSYSTEM = 0x00030000,
|
||||
SERVICE_STOP_REASON_MAJOR_SOFTWARE = 0x00040000,
|
||||
SERVICE_STOP_REASON_MAJOR_APPLICATION = 0x00050000,
|
||||
SERVICE_STOP_REASON_MAJOR_NONE = 0x00060000,
|
||||
SERVICE_STOP_REASON_MAJOR_MAX = 0x00070000,
|
||||
SERVICE_STOP_REASON_MAJOR_MIN_CUSTOM = 0x00400000,
|
||||
SERVICE_STOP_REASON_MAJOR_MAX_CUSTOM = 0x00ff0000,
|
||||
|
||||
//
|
||||
// Microsoft minor reasons. Update SERVICE_STOP_REASON_MINOR_MAX when
|
||||
// new codes are added.
|
||||
//
|
||||
SERVICE_STOP_REASON_MINOR_MIN = 0x00000000,
|
||||
SERVICE_STOP_REASON_MINOR_OTHER = 0x00000001,
|
||||
SERVICE_STOP_REASON_MINOR_MAINTENANCE = 0x00000002,
|
||||
SERVICE_STOP_REASON_MINOR_INSTALLATION = 0x00000003,
|
||||
SERVICE_STOP_REASON_MINOR_UPGRADE = 0x00000004,
|
||||
SERVICE_STOP_REASON_MINOR_RECONFIG = 0x00000005,
|
||||
SERVICE_STOP_REASON_MINOR_HUNG = 0x00000006,
|
||||
SERVICE_STOP_REASON_MINOR_UNSTABLE = 0x00000007,
|
||||
SERVICE_STOP_REASON_MINOR_DISK = 0x00000008,
|
||||
SERVICE_STOP_REASON_MINOR_NETWORKCARD = 0x00000009,
|
||||
SERVICE_STOP_REASON_MINOR_ENVIRONMENT = 0x0000000a,
|
||||
SERVICE_STOP_REASON_MINOR_HARDWARE_DRIVER = 0x0000000b,
|
||||
SERVICE_STOP_REASON_MINOR_OTHERDRIVER = 0x0000000c,
|
||||
SERVICE_STOP_REASON_MINOR_SERVICEPACK = 0x0000000d,
|
||||
SERVICE_STOP_REASON_MINOR_SOFTWARE_UPDATE = 0x0000000e,
|
||||
SERVICE_STOP_REASON_MINOR_SECURITYFIX = 0x0000000f,
|
||||
SERVICE_STOP_REASON_MINOR_SECURITY = 0x00000010,
|
||||
SERVICE_STOP_REASON_MINOR_NETWORK_CONNECTIVITY = 0x00000011,
|
||||
SERVICE_STOP_REASON_MINOR_WMI = 0x00000012,
|
||||
SERVICE_STOP_REASON_MINOR_SERVICEPACK_UNINSTALL = 0x00000013,
|
||||
SERVICE_STOP_REASON_MINOR_SOFTWARE_UPDATE_UNINSTALL = 0x00000014,
|
||||
SERVICE_STOP_REASON_MINOR_SECURITYFIX_UNINSTALL = 0x00000015,
|
||||
SERVICE_STOP_REASON_MINOR_MMC = 0x00000016,
|
||||
SERVICE_STOP_REASON_MINOR_NONE = 0x00000017,
|
||||
SERVICE_STOP_REASON_MINOR_MEMOTYLIMIT = 0x00000018,
|
||||
SERVICE_STOP_REASON_MINOR_MAX = 0x00000019,
|
||||
SERVICE_STOP_REASON_MINOR_MIN_CUSTOM = 0x00000100,
|
||||
SERVICE_STOP_REASON_MINOR_MAX_CUSTOM = 0x0000FFFF
|
||||
}
|
||||
|
||||
/*LPHANDLER_FUNCTION_EX callback
|
||||
/*LPHANDLER_FUNCTION_EX callback
|
||||
LPSERVICE_MAIN_FUNCTIONA callback
|
||||
LPSERVICE_MAIN_FUNCTIONW callback
|
||||
|
||||
|
@ -3539,6 +2920,7 @@ namespace Vanara.PInvoke
|
|||
QueryServiceLockStatus
|
||||
QueryServiceObjectSecurity
|
||||
QueryServiceStatus
|
||||
QueryServiceStatusEx
|
||||
SetServiceObjectSecurity
|
||||
StartServiceCtrlDispatcher
|
||||
StartService
|
||||
|
@ -3547,9 +2929,12 @@ namespace Vanara.PInvoke
|
|||
ENUM_SERVICE_STATUS_PROCESS
|
||||
ENUM_SERVICE_STATUS
|
||||
QUERY_SERVICE_LOCK_STATUS
|
||||
SERVICE_CONTROL_STATUS_REASON_PARAMS
|
||||
SERVICE_NOTIFY_2
|
||||
SERVICE_STATUS
|
||||
SERVICE_STATUS_PROCESS
|
||||
SERVICE_TABLE_ENTRY
|
||||
SERVICE_TIMECHANGE_INFO
|
||||
SERVICE_TRIGGER_SPECIFIC_DATA_ITEM */
|
||||
}
|
||||
}
|
||||
}
|
|
@ -402,126 +402,7 @@ namespace Vanara.PInvoke.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void OpenCloseSCManager()
|
||||
{
|
||||
using (var scm = AdvApi32.OpenSCManager(null, null, ScManagerAccessTypes.SC_MANAGER_CONNECT))
|
||||
{
|
||||
AssertHandleIsValid(scm);
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void OpenCloseService()
|
||||
{
|
||||
using (var scm = AdvApi32.OpenSCManager(null, null, ScManagerAccessTypes.SC_MANAGER_CONNECT))
|
||||
{
|
||||
AssertHandleIsValid(scm);
|
||||
|
||||
//opens task scheduler service
|
||||
using (var service = AdvApi32.OpenService(scm, "Schedule", ServiceAccessTypes.SERVICE_QUERY_STATUS))
|
||||
{
|
||||
AssertHandleIsValid(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void QueryServiceStatus()
|
||||
{
|
||||
using (var scm = AdvApi32.OpenSCManager(null, null, ScManagerAccessTypes.SC_MANAGER_CONNECT))
|
||||
{
|
||||
AssertHandleIsValid(scm);
|
||||
|
||||
//opens task scheduler service
|
||||
using (var service = AdvApi32.OpenService(scm, "Schedule", ServiceAccessTypes.SERVICE_QUERY_STATUS))
|
||||
{
|
||||
AssertHandleIsValid(service);
|
||||
|
||||
//query service status
|
||||
var ret3 = AdvApi32.QueryServiceStatusEx<SERVICE_STATUS_PROCESS>(service, ServiceStatusType.SC_STATUS_PROCESS_INFO, out var status);
|
||||
Assert.That(ret3, Is.True);
|
||||
|
||||
Assert.That(status.dwServiceType, Is.EqualTo(ServiceTypes.SERVICE_WIN32).Or.EqualTo(ServiceTypes.SERVICE_WIN32_SHARE_PROCESS));
|
||||
Assert.That(status.dwServiceFlags, Is.EqualTo(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test()]
|
||||
public void StartStopService()
|
||||
{
|
||||
using (var scm = AdvApi32.OpenSCManager(null, null, ScManagerAccessTypes.SC_MANAGER_CONNECT))
|
||||
{
|
||||
AssertHandleIsValid(scm);
|
||||
|
||||
var access = ServiceAccessTypes.SERVICE_START | ServiceAccessTypes.SERVICE_STOP | ServiceAccessTypes.SERVICE_QUERY_STATUS;
|
||||
|
||||
//opens print spooler service
|
||||
using (var service = AdvApi32.OpenService(scm, "Spooler", access))
|
||||
{
|
||||
AssertHandleIsValid(service);
|
||||
|
||||
//query service status
|
||||
var ret3 = AdvApi32.QueryServiceStatusEx<SERVICE_STATUS_PROCESS>(service, ServiceStatusType.SC_STATUS_PROCESS_INFO, out var status);
|
||||
if(!ret3) Win32Error.ThrowLastError();
|
||||
|
||||
if(status.dwCurrentState == ServiceState.SERVICE_RUNNING)
|
||||
{
|
||||
var ret4 = AdvApi32.StopService(service);
|
||||
if (!ret4) Win32Error.ThrowLastError();
|
||||
|
||||
WaitForServiceStatus(service, ServiceState.SERVICE_STOPPED);
|
||||
|
||||
var ret6 = AdvApi32.StartService(service);
|
||||
if (!ret6) Win32Error.ThrowLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
var ret4 = AdvApi32.StartService(service);
|
||||
if (!ret4) Win32Error.ThrowLastError();
|
||||
|
||||
WaitForServiceStatus(service, ServiceState.SERVICE_RUNNING);
|
||||
|
||||
var ret6 = AdvApi32.StopService(service);
|
||||
if (!ret6) Win32Error.ThrowLastError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void WaitForServiceStatus(SafeSC_HANDLE service, ServiceState status)
|
||||
{
|
||||
//query service status again to check that it changed
|
||||
var status2 = new SERVICE_STATUS_PROCESS();
|
||||
var tests = 0;
|
||||
|
||||
while (tests < 40)
|
||||
{
|
||||
var ret = AdvApi32.QueryServiceStatusEx<SERVICE_STATUS_PROCESS>(service, ServiceStatusType.SC_STATUS_PROCESS_INFO, out status2);
|
||||
if (!ret) Win32Error.ThrowLastError();
|
||||
if (status2.dwCurrentState == status)
|
||||
break;
|
||||
|
||||
Thread.Sleep(500);
|
||||
tests++;
|
||||
}
|
||||
|
||||
if (tests >= 40)
|
||||
throw new TimeoutException($"Timedout waiting for service status {status}");
|
||||
}
|
||||
|
||||
private static void AssertHandleIsValid(SafeSC_HANDLE handle)
|
||||
{
|
||||
if (handle.IsInvalid)
|
||||
Win32Error.ThrowLastError();
|
||||
|
||||
Assert.That(handle.IsNull, Is.False);
|
||||
Assert.That(handle.IsClosed, Is.False);
|
||||
Assert.That(handle.IsInvalid, Is.False);
|
||||
}
|
||||
|
||||
internal static object[] AuthCasesFromFile
|
||||
internal static object[] AuthCasesFromFile
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props')" />
|
||||
<Import Project="..\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
|
@ -275,7 +274,6 @@
|
|||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.11.0\build\NUnit.props'))" />
|
||||
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NUnit" version="3.11.0" targetFramework="net45" />
|
||||
<package id="NUnit3TestAdapter" version="3.12.0" targetFramework="net45" />
|
||||
</packages>
|
Loading…
Reference in New Issue