diff options
author | Gert Driesen <drieseng@users.sourceforge.net> | 2006-09-14 21:55:15 +0400 |
---|---|---|
committer | Gert Driesen <drieseng@users.sourceforge.net> | 2006-09-14 21:55:15 +0400 |
commit | d90d4b0cbe6d32ec87b1876aed9501298da3b7aa (patch) | |
tree | 27e456bfaed688458623650c6329c60ab10eef3a | |
parent | 8237aaef8514f794767ca88865fe72089ad4bdc9 (diff) |
* ServiceControllerPermissionTest.cs: Set eol-style to native. Fixed
warning and improved Union_Null test.
* ServiceControllerPermissionAttributeTest.cs: Set eol-style to native.
Fixed warning.
* ServiceControllerTest.cs: Added unit tests for win32 implementation
of ServiceController.
* ServiceControllerPermissionEntryCollection.cs: Set eol-style to
native.
* ServiceAccount.cs: Set eol-style to native.
* ServiceControllerPermission.cs: Set eol-style to native.
* ServiceProcessInstaller.cs: Set eol-style to native.
* ServiceInstaller.cs: API compatibility fixes. Coding guidelines
fixes. Set eol-style to native.
* PowerBroadcastStatus.cs: Removed Serializable attribute. Coding
guidelines fixes. Set eol-style to native.
* ServiceStartMode.cs: Removed Serializable attribute. Coding
guidelines fixes. Set eol-style to native.
* ServiceProcessDescriptionAttribute.cs: Removed Serializable
attribute. Set eol-style to native.
* ServiceBase.cs: Set eol-style to native.
* ServiceControllerPermissionAccess.cs: Removed Serializable
attribute. Coding guidelines fixes. Set eol-style to native.
* ServiceControllerPermissionAccess.cs: Set eol-style to native.
* ServiceControllerPermissionEntry.cs: Set eol-style to native.
* ServiceControllerPermissionAttribute.cs: Set eol-style to native.
* ServiceType.cs: Removed Serializable attribute. Coding guidelines
fixes. Set eol-style to native.
* ServiceController.cs: API compatibility fixes. Added missing
MonoTODO's. Coding guidelines fixes. Set eol-style to native.
Provides an implementation for Win32.
* TimeoutException.cs: Set eol-style to native.
* ServiceControllerStatus.cs: Removed Serializable attribute.
Coding guidelines fixes. Set eol-style to native.
* UnixServiceController.cs: Dummy implementation for unix. Always
throws NotImplementedException.
* Win32ServiceController.cs: Win32 implementation. Built as a wrapper
for the Win32 Service API.
* Makefile: Treat warnings as error. Ignore no warnings.
* System.ServiceProcess.dll.sources: Added ServiceControllerImpl.cs,
UnixServiceController.cs and Win32ServiceController.cs.
* System.ServiceProcess_test.dll.sources: Added
ServiceControllerTest.cs.
svn path=/trunk/mcs/; revision=65422
20 files changed, 6675 insertions, 57 deletions
diff --git a/mcs/class/System.ServiceProcess/ChangeLog b/mcs/class/System.ServiceProcess/ChangeLog index d6aeaffa9a8..79443b551da 100644 --- a/mcs/class/System.ServiceProcess/ChangeLog +++ b/mcs/class/System.ServiceProcess/ChangeLog @@ -1,3 +1,11 @@ +2006-09-14 Gert Driesen <drieseng@users.sourceforge.net> + + * Makefile: Treat warnings as error. Ignore no warnings. + * System.ServiceProcess.dll.sources: Added ServiceControllerImpl.cs, + UnixServiceController.cs and Win32ServiceController.cs. + * System.ServiceProcess_test.dll.sources: Added + ServiceControllerTest.cs. + 2005-01-23 Geoff Norton <gnorton@customerdna.com> * System.ServiceProcess.dll.sources: Add ServiceInstaller and diff --git a/mcs/class/System.ServiceProcess/Makefile b/mcs/class/System.ServiceProcess/Makefile index c53d28f9d0f..3e1e6f988ce 100644 --- a/mcs/class/System.ServiceProcess/Makefile +++ b/mcs/class/System.ServiceProcess/Makefile @@ -3,8 +3,8 @@ SUBDIRS = include ../../build/rules.make LIBRARY = System.ServiceProcess.dll -LIB_MCS_FLAGS = /r:System.dll /r:System.Configuration.Install.dll -TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -nowarn:0618 -nowarn:219 -nowarn:169 +LIB_MCS_FLAGS = /r:System.dll /r:System.Configuration.Install.dll /warnaserror +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) /warnaserror EXTRA_DISTFILES = diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess.dll.sources b/mcs/class/System.ServiceProcess/System.ServiceProcess.dll.sources index bf6ca164d58..3953b2ac62d 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess.dll.sources +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess.dll.sources @@ -5,6 +5,7 @@ Assembly/AssemblyInfo.cs System.ServiceProcess/PowerBroadcastStatus.cs System.ServiceProcess/ServiceAccount.cs System.ServiceProcess/ServiceController.cs +System.ServiceProcess/ServiceControllerImpl.cs System.ServiceProcess/ServiceControllerPermissionAccess.cs System.ServiceProcess/ServiceControllerStatus.cs System.ServiceProcess/ServiceInstaller.cs @@ -18,3 +19,5 @@ System.ServiceProcess/ServiceControllerPermission.cs System.ServiceProcess/ServiceControllerPermissionAttribute.cs System.ServiceProcess/ServiceControllerPermissionEntry.cs System.ServiceProcess/ServiceControllerPermissionEntryCollection.cs +System.ServiceProcess/UnixServiceController.cs +System.ServiceProcess/Win32ServiceController.cs diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ChangeLog b/mcs/class/System.ServiceProcess/System.ServiceProcess/ChangeLog index e1abfbf8f96..7db2de6a15a 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ChangeLog +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ChangeLog @@ -1,3 +1,37 @@ +2006-09-14 Gert Driesen <drieseng@users.sourceforge.net> + + * ServiceControllerPermissionEntryCollection.cs: Set eol-style to + native. + * ServiceAccount.cs: Set eol-style to native. + * ServiceControllerPermission.cs: Set eol-style to native. + * ServiceProcessInstaller.cs: Set eol-style to native. + * ServiceInstaller.cs: API compatibility fixes. Coding guidelines + fixes. Set eol-style to native. + * PowerBroadcastStatus.cs: Removed Serializable attribute. Coding + guidelines fixes. Set eol-style to native. + * ServiceStartMode.cs: Removed Serializable attribute. Coding + guidelines fixes. Set eol-style to native. + * ServiceProcessDescriptionAttribute.cs: Removed Serializable + attribute. Set eol-style to native. + * ServiceBase.cs: Set eol-style to native. + * ServiceControllerPermissionAccess.cs: Removed Serializable + attribute. Coding guidelines fixes. Set eol-style to native. + * ServiceControllerPermissionAccess.cs: Set eol-style to native. + * ServiceControllerPermissionEntry.cs: Set eol-style to native. + * ServiceControllerPermissionAttribute.cs: Set eol-style to native. + * ServiceType.cs: Removed Serializable attribute. Coding guidelines + fixes. Set eol-style to native. + * ServiceController.cs: API compatibility fixes. Added missing + MonoTODO's. Coding guidelines fixes. Set eol-style to native. + Provides an implementation for Win32. + * TimeoutException.cs: Set eol-style to native. + * ServiceControllerStatus.cs: Removed Serializable attribute. + Coding guidelines fixes. Set eol-style to native. + * UnixServiceController.cs: Dummy implementation for unix. Always + throws NotImplementedException. + * Win32ServiceController.cs: Win32 implementation. Built as a wrapper + for the Win32 Service API. + 2006-01-13 Ben Maurer <bmaurer@andrew.cmu.edu> * ServiceInstaller.cs: Stubs for 2.0 stuff diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/PowerBroadcastStatus.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/PowerBroadcastStatus.cs index 1b12bfa7813..e6b4c064431 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/PowerBroadcastStatus.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/PowerBroadcastStatus.cs @@ -28,8 +28,8 @@ namespace System.ServiceProcess { - [Serializable] - public enum PowerBroadcastStatus { + public enum PowerBroadcastStatus + { QuerySuspend = 0, QuerySuspendFailed = 2, Suspend = 4, diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceController.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceController.cs index 8f497ee63cb..831d7a71234 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceController.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceController.cs @@ -1,10 +1,12 @@ // // System.ServiceProcess.ServiceController // -// Author: Marek Safar (marek.safar@seznam.cz) +// Authors: +// Marek Safar (marek.safar@seznam.cz) +// Gert Driesen (drieseng@users.sourceforge.net) // // (C) 2005, Marek Safar - +// // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -25,70 +27,454 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +// TODO: check if there's more information to cache (eg. status) +// Start / Stop / ... using System; using System.ComponentModel; +using System.Globalization; +#if NET_2_0 +using System.Runtime.InteropServices; +#endif +using System.Threading; namespace System.ServiceProcess { + [Designer("System.ServiceProcess.Design.ServiceControllerDesigner, " + Consts.AssemblySystem_Design)] public class ServiceController : Component { + private string _name; + private string _serviceName = string.Empty; + private string _machineName; + private string _displayName = string.Empty; + private readonly ServiceControllerImpl _impl; + private ServiceController [] _dependentServices; + private ServiceController [] _servicesDependedOn; - [MonoTODO] - public ServiceController () {} - public ServiceController (string name) {} - public ServiceController (string name, string machineName) {} + [MonoTODO ("No unix implementation")] + public ServiceController () + { + _machineName = "."; + _name = string.Empty; + _impl = CreateServiceControllerImpl (this); + } - [MonoTODO] - public ServiceControllerStatus Status { + [MonoTODO ("No unix implementation")] + public ServiceController (string name) : this (name, ".") + { + } + + [MonoTODO ("No unix implementation")] + public ServiceController (string name, string machineName) + { + if (name == null || name.Length == 0) + throw new ArgumentException (string.Format (CultureInfo.CurrentCulture, + "Invalid value {0} for parameter name.", name)); + + ValidateMachineName (machineName); + + _machineName = machineName; + _name = name; + _impl = CreateServiceControllerImpl (this); + } + + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public bool CanPauseAndContinue { get { - throw new NotImplementedException (); +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + return _impl.CanPauseAndContinue; } } - [MonoTODO] + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public bool CanShutdown { + get + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + return _impl.CanShutdown; + } + } + + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public bool CanStop { + get + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + return _impl.CanStop; + } + } + + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public ServiceController [] DependentServices { + get + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + if (_dependentServices == null) + _dependentServices = _impl.DependentServices; + return _dependentServices; + } + } + + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ReadOnly (true)] + [ServiceProcessDescription ("")] + public string DisplayName { + get { + if (_displayName.Length == 0 && (_serviceName.Length > 0 || _name.Length > 0)) + _displayName = _impl.DisplayName; + return _displayName; + } + set { + if (value == null) + throw new ArgumentNullException ("value"); + + if (_displayName == value) + return; + + _displayName = value; + + // if display name is modified, then we also need to force a + // new lookup of the corresponding service name + _serviceName = string.Empty; + + // you'd expect the DependentServices and ServiceDependedOn cache + // to be cleared too, but the MS implementation doesn't do this + // + // bug submitted: + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + + // release any handles and clear cache + Close (); + } + } + + [MonoTODO ("No unix implementation")] + [Browsable (false)] + [DefaultValue (".")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public string MachineName { + get { + return _machineName; + } + set { + ValidateMachineName (value); + + if (_machineName == value) + return; + + _machineName = value; + + // you'd expect the DependentServices and ServiceDependedOn cache + // to be cleared too, but the MS implementation doesn't do this + // + // bug submitted: + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + + // release any handles and clear cache + Close (); + } + } + + [MonoTODO ("No unix implementation")] + [DefaultValue ("")] + [ReadOnly (true)] + [RecommendedAsConfigurable (true)] + [ServiceProcessDescription ("")] public string ServiceName { - get { - throw new NotImplementedException (); + get { + if (_serviceName.Length == 0 && (_displayName.Length > 0 || _name.Length > 0)) + _serviceName = _impl.ServiceName; + return _serviceName; } - set { - throw new NotImplementedException (); + set { + if (value == null) + throw new ArgumentNullException ("value"); + + if (_serviceName == value) + return; + +#if NET_2_0 + ValidateServiceName (value); +#endif + + _serviceName = value; + + // if service name is modified, then we also need to force a + // new lookup of the corresponding display name + _displayName = string.Empty; + + // you'd expect the DependentServices and ServiceDependedOn cache + // to be cleared too, but the MS implementation doesn't do this + // + // bug submitted: + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + + // release any handles and clear cache + Close (); + } + } + + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public ServiceController [] ServicesDependedOn { + get + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + if (_servicesDependedOn == null) + _servicesDependedOn = _impl.ServicesDependedOn; + return _servicesDependedOn; } } +#if NET_2_0 [MonoTODO] + [Browsable (false)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public SafeHandle ServiceHandle + { + get { + throw new NotImplementedException (); + } + } +#endif + + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public ServiceType ServiceType { + get + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + return _impl.ServiceType; + } + } + + [MonoTODO ("No unix implementation")] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + [ServiceProcessDescription ("")] + public ServiceControllerStatus Status { + get + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + return _impl.Status; + } + } + + [MonoTODO ("No unix implementation")] + public void Close () + { + _impl.Close (); + } + + [MonoTODO ("No unix implementation")] + public void Continue () + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + _impl.Continue (); + } + + [MonoTODO ("No unix implementation")] + protected override void Dispose (bool disposing) + { + _impl.Dispose (disposing); + base.Dispose (disposing); + } + + [MonoTODO ("No unix implementation")] + public void ExecuteCommand (int command) + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + _impl.ExecuteCommand (command); + } + + [MonoTODO ("No unix implementation")] + public static ServiceController[] GetDevices () + { + return GetDevices ("."); + } + + [MonoTODO ("No unix implementation")] + public static ServiceController[] GetDevices (string machineName) + { + ValidateMachineName (machineName); + + using (ServiceController sc = new ServiceController ("dummy", machineName)) { + ServiceControllerImpl impl = CreateServiceControllerImpl (sc); + return impl.GetDevices (); + } + } + + [MonoTODO ("No unix implementation")] public static ServiceController[] GetServices () { - throw new NotImplementedException (); + return GetServices ("."); } - - [MonoTODO] - public void Stop () { - throw new NotImplementedException (); + + [MonoTODO ("No unix implementation")] + public static ServiceController[] GetServices (string machineName) + { + ValidateMachineName (machineName); + + using (ServiceController sc = new ServiceController ("dummy", machineName)) { + ServiceControllerImpl impl = CreateServiceControllerImpl (sc); + return impl.GetServices (); + } } - [MonoTODO] + [MonoTODO ("No unix implementation")] + public void Pause () + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + _impl.Pause (); + } + + [MonoTODO ("No unix implementation")] + public void Refresh () + { + // MSDN: this method also sets the ServicesDependedOn and + // DependentServices properties to a null reference + // + // I assume they wanted to say that the cache for these properties + // is cleared. Verified by unit tests. + _dependentServices = null; + _servicesDependedOn = null; + _impl.Refresh (); + } + + [MonoTODO ("No unix implementation")] public void Start () { - throw new NotImplementedException (); + Start (new string [0]); } + [MonoTODO ("No unix implementation")] public void Start (string [] args) { - throw new NotImplementedException (); +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + _impl.Start (args); } - [MonoTODO] - public void WaitForStatus (ServiceControllerStatus desiredStatus){ - throw new NotImplementedException (); + [MonoTODO ("No unix implementation")] + public void Stop () + { +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + _impl.Stop (); } - [MonoTODO] + [MonoTODO ("No unix implementation")] + public void WaitForStatus (ServiceControllerStatus desiredStatus) + { + WaitForStatus (desiredStatus, TimeSpan.MaxValue); + } + + [MonoTODO ("No unix implementation")] public void WaitForStatus (ServiceControllerStatus desiredStatus, TimeSpan timeout) { - throw new NotImplementedException (); +#if NET_2_0 + ValidateServiceName (ServiceName); +#endif + + DateTime start = DateTime.Now; + while (Status != desiredStatus) { + if (timeout < (DateTime.Now - start)) + throw new TimeoutException ("Time out has expired and the" + + " operation has not been completed."); + Thread.Sleep (100); + // force refresh of status + Refresh (); + } } - + internal string Name { + get { + return _name; + } + set { + _name = value; + } + } + + internal string InternalDisplayName { + get { + return _displayName; + } + set { + _displayName = value; + } + } + + internal string InternalServiceName { + get { + return _serviceName; + } + set { + _serviceName = value; + } + } + +#if NET_2_0 + private static void ValidateServiceName (string serviceName) + { + if (serviceName.Length == 0 || serviceName.Length > 80) + throw new ArgumentException (string.Format (CultureInfo.CurrentCulture, + "Service name {0} contains invalid characters, is empty" + + " or is too long (max length = 80).", serviceName)); + } +#endif + + private static void ValidateMachineName (string machineName) + { + if (machineName == null || machineName.Length == 0) + throw new ArgumentException (string.Format (CultureInfo.CurrentCulture, + "MachineName value {0} is invalid.", machineName)); + } + + private static ServiceControllerImpl CreateServiceControllerImpl (ServiceController serviceController) + { +#if NET_2_0 + if (Environment.OSVersion.Platform == PlatformID.Unix) { +#else + if ((int) Environment.OSVersion.Platform == 128) { +#endif + return new UnixServiceController (serviceController); + } else { + return new Win32ServiceController (serviceController); + } + } } } diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerImpl.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerImpl.cs new file mode 100644 index 00000000000..6cd389c289c --- /dev/null +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerImpl.cs @@ -0,0 +1,104 @@ +// +// System.ServiceProcess.ServiceControllerImpl +// +// Author: +// Gert Driesen (drieseng@users.sourceforge.net) +// +// Copyright (C) 2006 Novell, Inc (http://www.novell.com) +// +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace System.ServiceProcess +{ + internal abstract class ServiceControllerImpl + { + protected ServiceControllerImpl (ServiceController serviceController) + { + _serviceController = serviceController; + } + + protected ServiceController ServiceController { + get { + return _serviceController; + } + } + + public abstract bool CanPauseAndContinue { + get; + } + + public abstract bool CanShutdown { + get; + } + + public abstract bool CanStop { + get; + } + + public abstract ServiceController [] DependentServices { + get; + } + + public abstract string DisplayName { + get; + } + + public abstract string ServiceName { + get; + } + + public abstract ServiceController [] ServicesDependedOn { + get; + } + + public abstract ServiceType ServiceType { + get; + } + + public abstract ServiceControllerStatus Status + { + get; + } + + public abstract void Close (); + + public abstract void Continue (); + + public abstract void Dispose (bool disposing); + + public abstract void ExecuteCommand (int command); + + public abstract ServiceController [] GetDevices (); + + public abstract ServiceController [] GetServices (); + + public abstract void Pause (); + + public abstract void Refresh (); + + public abstract void Start (string [] args); + + public abstract void Stop (); + + private readonly ServiceController _serviceController; + } +} diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerPermissionAccess.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerPermissionAccess.cs index 9fca34e970b..c4744e81ab1 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerPermissionAccess.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerPermissionAccess.cs @@ -28,13 +28,12 @@ // namespace System.ServiceProcess -{ +{ [Flags] - [Serializable] - public enum ServiceControllerPermissionAccess { + public enum ServiceControllerPermissionAccess + { None = 0, Browse = 2, Control = 6, - } } diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerStatus.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerStatus.cs index f0972b94445..f3de2e06fb0 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerStatus.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceControllerStatus.cs @@ -28,9 +28,9 @@ // namespace System.ServiceProcess -{ - [Serializable] - public enum ServiceControllerStatus { +{ + public enum ServiceControllerStatus + { Stopped = 1, StartPending = 2, StopPending = 3, @@ -40,4 +40,3 @@ namespace System.ServiceProcess Paused = 7 } } - diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceInstaller.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceInstaller.cs index 8893836cd9c..b7300617652 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceInstaller.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceInstaller.cs @@ -28,17 +28,22 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // - using System; using System.Collections; using System.ComponentModel; using System.Configuration.Install; +#if NET_2_0 +using System.Runtime.InteropServices; +#endif namespace System.ServiceProcess { - public class ServiceInstaller : System.Configuration.Install.ComponentInstaller + [MonoTODO] + public class ServiceInstaller : ComponentInstaller { - public ServiceInstaller () {} + public ServiceInstaller () + { + } private string display_name; private string service_name; @@ -47,6 +52,10 @@ namespace System.ServiceProcess #if NET_2_0 private string description; + + [ComVisible (false)] + [DefaultValue ("")] + [ServiceProcessDescription ("")] public string Description { get { return description; @@ -57,6 +66,7 @@ namespace System.ServiceProcess } #endif + [DefaultValue("")] public string DisplayName { get { return display_name; @@ -66,6 +76,8 @@ namespace System.ServiceProcess } } + [DefaultValue("")] + [TypeConverter("System.Diagnostics.Design.StringValueConverter, " + Consts.AssemblySystem_Design)] public string ServiceName { get { return service_name; @@ -86,6 +98,7 @@ namespace System.ServiceProcess } } + [DefaultValue (ServiceStartMode.Manual)] public ServiceStartMode StartType { get { return start_type; @@ -95,24 +108,29 @@ namespace System.ServiceProcess } } - public override void CopyFromComponent (IComponent component) { + public override void CopyFromComponent (IComponent component) + { if (!component.GetType ().IsSubclassOf (typeof (ServiceBase))) throw new ArgumentException (); } - public override void Install (IDictionary stateSaver) { + public override void Install (IDictionary stateSaver) + { throw new NotImplementedException (); } - public override bool IsEquivalentInstaller (ComponentInstaller otherInstaller) { + public override bool IsEquivalentInstaller (ComponentInstaller otherInstaller) + { throw new NotImplementedException (); } - public override void Rollback (IDictionary savedState) { + public override void Rollback (IDictionary savedState) + { throw new NotImplementedException (); } - public override void Uninstall (IDictionary savedState) { + public override void Uninstall (IDictionary savedState) + { throw new NotImplementedException (); } } diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceProcessDescriptionAttribute.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceProcessDescriptionAttribute.cs index d1aec5cee74..4aae3867ea6 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceProcessDescriptionAttribute.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceProcessDescriptionAttribute.cs @@ -33,7 +33,6 @@ using System.ComponentModel; namespace System.ServiceProcess { - [Serializable] [AttributeUsage (AttributeTargets.All)] public class ServiceProcessDescriptionAttribute : DescriptionAttribute { diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceStartMode.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceStartMode.cs index 99f1a86e789..01fe8bae311 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceStartMode.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceStartMode.cs @@ -28,9 +28,9 @@ // namespace System.ServiceProcess -{ - [Serializable] - public enum ServiceStartMode { +{ + public enum ServiceStartMode + { Automatic = 2, Manual = 3, Disabled = 4 diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceType.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceType.cs index 1f1c0ec3c5a..48cb05c5c3e 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceType.cs +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/ServiceType.cs @@ -28,10 +28,10 @@ // namespace System.ServiceProcess -{ +{ [Flags] - [Serializable] - public enum ServiceType { + public enum ServiceType + { KernelDriver = 1, FileSystemDriver = 2, Adapter = 4, diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/UnixServiceController.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/UnixServiceController.cs new file mode 100644 index 00000000000..cb74c79b20a --- /dev/null +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/UnixServiceController.cs @@ -0,0 +1,142 @@ +// +// System.ServiceProcess.UnixServiceController +// +// Author: +// Gert Driesen (drieseng@users.sourceforge.net) +// +// Copyright (C) 2006 Novell, Inc (http://www.novell.com) +// +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace System.ServiceProcess +{ + internal class UnixServiceController : ServiceControllerImpl + { + public UnixServiceController (ServiceController serviceController) + : base (serviceController) + { + } + + public override bool CanPauseAndContinue { + get { + throw new NotImplementedException (); + } + } + + public override bool CanShutdown { + get { + throw new NotImplementedException (); + } + } + + public override bool CanStop { + get { + throw new NotImplementedException (); + } + } + + public override ServiceController [] DependentServices { + get { + throw new NotImplementedException (); + } + } + + public override string DisplayName { + get { + throw new NotImplementedException (); + } + } + + public override string ServiceName { + get { + throw new NotImplementedException (); + } + } + + public override ServiceController [] ServicesDependedOn { + get { + throw new NotImplementedException (); + } + } + + public override ServiceType ServiceType { + get { + throw new NotImplementedException (); + } + } + + public override ServiceControllerStatus Status { + get { + throw new NotImplementedException (); + } + } + + public override void Close () + { + throw new NotImplementedException (); + } + + public override void Continue () + { + throw new NotImplementedException (); + } + + public override void Dispose (bool disposing) + { + } + + public override void ExecuteCommand (int command) + { + throw new NotImplementedException (); + } + + public override ServiceController [] GetDevices () + { + throw new NotImplementedException (); + } + + public override ServiceController [] GetServices () + { + throw new NotImplementedException (); + } + + public override void Pause () + { + throw new NotImplementedException (); + } + + public override void Refresh () + { + throw new NotImplementedException (); + } + + public override void Start (string [] args) + { + throw new NotImplementedException (); + } + + public override void Stop () + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess/Win32ServiceController.cs b/mcs/class/System.ServiceProcess/System.ServiceProcess/Win32ServiceController.cs new file mode 100644 index 00000000000..f15d4a59b25 --- /dev/null +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess/Win32ServiceController.cs @@ -0,0 +1,946 @@ +// +// System.ServiceProcess.Win32ServiceController +// +// Author: +// Gert Driesen (drieseng@users.sourceforge.net) +// +// Copyright (C) 2006 Novell, Inc (http://www.novell.com) +// +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Collections; +using System.ComponentModel; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; + +namespace System.ServiceProcess +{ + internal class Win32ServiceController : ServiceControllerImpl + { + SERVICE_STATUS_PROCESS _status; + + public Win32ServiceController (ServiceController serviceController) + : base (serviceController) + { + } + + public override bool CanPauseAndContinue { + get { + if ((int) _status.dwServiceType == 0) + _status = GetServiceStatus (ServiceController.ServiceName, + ServiceController.MachineName); + return (_status.dwControlsAccepted & SERVICE_CONTROL_ACCEPTED.SERVICE_ACCEPT_PAUSE_CONTINUE) != 0; + } + } + + public override bool CanShutdown { + get { + if ((int) _status.dwServiceType == 0) + _status = GetServiceStatus (ServiceController.ServiceName, + ServiceController.MachineName); + return (_status.dwControlsAccepted & SERVICE_CONTROL_ACCEPTED.SERVICE_ACCEPT_SHUTDOWN) != 0; + } + } + + public override bool CanStop { + get { + if ((int) _status.dwServiceType == 0) + _status = GetServiceStatus (ServiceController.ServiceName, + ServiceController.MachineName); + return (_status.dwControlsAccepted & SERVICE_CONTROL_ACCEPTED.SERVICE_ACCEPT_STOP) != 0; + } + } + + public override ServiceController [] DependentServices { + get { + return GetDependentServices (ServiceController.ServiceName, + ServiceController.MachineName); + } + } + + public override string DisplayName { + get { + string lookupName = ServiceController.ServiceName; + + IntPtr scHandle = IntPtr.Zero; + try { + scHandle = OpenServiceControlManager (ServiceController.MachineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + if (lookupName.Length == 0) { + // if the service name is not available, then + // assume the specified name is in fact already a display + // name + try { + string serviceName = GetServiceName (scHandle, + lookupName); + ServiceController.InternalServiceName = serviceName; + ServiceController.Name = string.Empty; + return lookupName; + } catch (Win32Exception) { + } + } + + if (ServiceController.InternalDisplayName.Length == 0) + return GetServiceDisplayName (scHandle, lookupName, + ServiceController.MachineName); + return ServiceController.InternalDisplayName; + } finally { + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + } + } + } + + public override string ServiceName { + get { + string lookupName = ServiceController.Name; + if (lookupName.Length == 0) + lookupName = ServiceController.InternalDisplayName; + + IntPtr scHandle = IntPtr.Zero; + try { + scHandle = OpenServiceControlManager (ServiceController.MachineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + // assume the specified name is in fact a display name + try { + string serviceName = GetServiceName (scHandle, lookupName); + ServiceController.InternalDisplayName = lookupName; + ServiceController.Name = string.Empty; + return serviceName; + } catch (Win32Exception) { + } + + // instead of opening the service to verify whether it exists, + // we'll try to get its displayname and hereby avoid looking + // this up separately + string displayName = GetServiceDisplayName (scHandle, + lookupName, ServiceController.MachineName); + ServiceController.InternalDisplayName = displayName; + ServiceController.Name = string.Empty; + return lookupName; + } finally { + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + } + } + } + + public override ServiceController [] ServicesDependedOn { + get { + return GetServiceDependencies (ServiceController.ServiceName, + ServiceController.MachineName); + } + } + + public override ServiceType ServiceType { + get { + if ((int) _status.dwServiceType == 0) + _status = GetServiceStatus (ServiceController.ServiceName, + ServiceController.MachineName); + return _status.dwServiceType; + } + } + + public override ServiceControllerStatus Status { + get { + if ((int) _status.dwServiceType == 0) + _status = GetServiceStatus (ServiceController.ServiceName, + ServiceController.MachineName); + return _status.dwCurrentState; + } + } + + public override void Close () + { + // clear status cache + _status.dwServiceType = 0; + } + + public override void Continue () + { + string serviceName = ServiceController.ServiceName; + string machineName = ServiceController.MachineName; + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_PAUSE_CONTINUE); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, + machineName); + + SERVICE_STATUS status = new SERVICE_STATUS (); + if (!ControlService (svcHandle, SERVICE_CONTROL_TYPE.SERVICE_CONTROL_CONTINUE, ref status)) + throw new InvalidOperationException (string.Format ( + CultureInfo.CurrentCulture, "Cannot resume {0} service" + + " on computer '{1}'.", serviceName, machineName), + new Win32Exception ()); + } finally { + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + } + } + + public override void Dispose (bool disposing) + { + // we're not keeping any handles open + } + + public override void ExecuteCommand (int command) + { + string serviceName = ServiceController.ServiceName; + string machineName = ServiceController.MachineName; + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + // MSDN: the hService handle must have the SERVICE_USER_DEFINED_CONTROL + // access right + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_USER_DEFINED_CONTROL); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, + machineName); + + SERVICE_STATUS status = new SERVICE_STATUS (); + if (!ControlService (svcHandle, (SERVICE_CONTROL_TYPE) command, ref status)) + throw new InvalidOperationException (string.Format ( + CultureInfo.CurrentCulture, "Cannot control {0} service" + + " on computer '{1}'.", serviceName, machineName), + new Win32Exception ()); + } finally { + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + } + } + + public override ServiceController [] GetDevices () + { + return GetServices (ServiceController.MachineName, + SERVICE_TYPE.SERVICE_DRIVER, null); + } + + public override ServiceController [] GetServices () + { + return GetServices (ServiceController.MachineName, + SERVICE_TYPE.SERVICE_WIN32, null); + } + + public override void Pause () + { + string serviceName = ServiceController.ServiceName; + string machineName = ServiceController.MachineName; + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_PAUSE_CONTINUE); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, + machineName); + + SERVICE_STATUS status = new SERVICE_STATUS (); + if (!ControlService (svcHandle, SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE, ref status)) + throw new InvalidOperationException (string.Format ( + CultureInfo.CurrentCulture, "Cannot pause {0} service" + + " on computer '{1}'.", serviceName, machineName), + new Win32Exception ()); + } finally { + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + } + } + + public override void Refresh () + { + // force refresh of status + _status.dwServiceType = 0; + } + + public override void Start (string [] args) + { + string serviceName = ServiceController.ServiceName; + string machineName = ServiceController.MachineName; + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + IntPtr [] arguments = new IntPtr [args.Length]; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_START); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, + machineName); + + for (int i = 0; i < args.Length; i++) { + string argument = args [i]; + arguments [i] = Marshal.StringToHGlobalAnsi (argument); + } + + if (!StartService (svcHandle, arguments.Length, arguments)) + throw new InvalidOperationException (string.Format ( + CultureInfo.CurrentCulture, "Cannot start {0} service" + + " on computer '{1}'.", serviceName, machineName), + new Win32Exception ()); + } finally { + for (int i = 0; i < arguments.Length; i++) + Marshal.FreeHGlobal (arguments [i]); + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + } + + } + + public override void Stop () + { + string serviceName = ServiceController.ServiceName; + string machineName = ServiceController.MachineName; + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_STOP); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, + machineName); + + SERVICE_STATUS status = new SERVICE_STATUS (); + if (!ControlService (svcHandle, SERVICE_CONTROL_TYPE.SERVICE_CONTROL_STOP, ref status)) + throw new InvalidOperationException (string.Format ( + CultureInfo.CurrentCulture, "Cannot stop {0} service" + + " on computer '{1}'.", serviceName, machineName), + new Win32Exception ()); + } finally { + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + } + } + + private static ServiceController [] GetDependentServices (string serviceName, string machineName) + { + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + IntPtr buffer = IntPtr.Zero; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_ENUMERATE_DEPENDENTS); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, machineName); + + uint bufferSize = 0; + uint bytesNeeded = 0; + uint servicesReturned = 0; + + ServiceController [] services; + + while (true) { + if (!EnumDependentServices (svcHandle, SERVICE_STATE_REQUEST.SERVICE_STATE_ALL, buffer, bufferSize, out bytesNeeded, out servicesReturned)) { + int err = Marshal.GetLastWin32Error (); + if (err == ERROR_MORE_DATA) { + buffer = Marshal.AllocHGlobal ((int) bytesNeeded); + bufferSize = bytesNeeded; + } else { + throw new Win32Exception (err); + } + } else { + int iPtr = buffer.ToInt32 (); + + services = new ServiceController [servicesReturned]; + for (int i = 0; i < servicesReturned; i++) { + ENUM_SERVICE_STATUS serviceStatus = (ENUM_SERVICE_STATUS) Marshal.PtrToStructure ( + new IntPtr (iPtr), typeof (ENUM_SERVICE_STATUS)); + // TODO: use internal ctor that takes displayname too ? + services [i] = new ServiceController (serviceStatus.pServiceName, + machineName); + // move on to the next services + iPtr += ENUM_SERVICE_STATUS.SizeOf; + } + + // we're done, so exit the loop + break; + } + } + + return services; + } finally { + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal (buffer); + } + } + + private static ServiceController [] GetServiceDependencies (string serviceName, string machineName) + { + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + IntPtr buffer = IntPtr.Zero; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_QUERY_CONFIG); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, machineName); + + uint bufferSize = 0; + uint bytesNeeded = 0; + + ServiceController [] services; + + while (true) { + if (!QueryServiceConfig (svcHandle, buffer, bufferSize, out bytesNeeded)) { + int err = Marshal.GetLastWin32Error (); + if (err == ERROR_INSUFFICIENT_BUFFER) { + buffer = Marshal.AllocHGlobal ((int) bytesNeeded); + bufferSize = bytesNeeded; + } else { + throw new Win32Exception (err); + } + } else { + QUERY_SERVICE_CONFIG config = (QUERY_SERVICE_CONFIG) Marshal.PtrToStructure ( + buffer, typeof (QUERY_SERVICE_CONFIG)); + + Hashtable depServices = new Hashtable (); + IntPtr iPtr = config.lpDependencies; + StringBuilder sb = new StringBuilder (); + string currentChar = Marshal.PtrToStringUni (iPtr, 1); + while (currentChar != "\0") { + sb.Append (currentChar); + iPtr = new IntPtr (iPtr.ToInt64 () + Marshal.SystemDefaultCharSize); + currentChar = Marshal.PtrToStringUni (iPtr, 1); + if (currentChar != "\0") { + continue; + } + iPtr = new IntPtr (iPtr.ToInt64 () + Marshal.SystemDefaultCharSize); + currentChar = Marshal.PtrToStringUni (iPtr, 1); + string dependency = sb.ToString (); + if (dependency [0] == SC_GROUP_IDENTIFIER) { + ServiceController [] groupServices = GetServices ( + machineName, SERVICE_TYPE.SERVICE_WIN32, + dependency.Substring (1)); + foreach (ServiceController sc in groupServices) { + if (!depServices.Contains (sc.ServiceName)) + depServices.Add (sc.ServiceName, sc); + } + } else if (!depServices.Contains (dependency)) { + depServices.Add (dependency, new ServiceController (dependency, machineName)); + } + sb.Length = 0; + } + + services = new ServiceController [depServices.Count]; + depServices.Values.CopyTo (services, 0); + break; + } + } + + return services; + } finally { + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal (buffer); + } + } + + private static string GetServiceDisplayName (IntPtr scHandle, string serviceName, string machineName) + { + StringBuilder buffer = new StringBuilder (); + + uint bufferSize = (uint) buffer.Capacity; + + while (true) { + if (!GetServiceDisplayName (scHandle, serviceName, buffer, ref bufferSize)) { + int err = Marshal.GetLastWin32Error (); + if (err == ERROR_INSUFFICIENT_BUFFER) { + // allocate additional byte for terminating null char + buffer = new StringBuilder ((int) bufferSize + 1); + bufferSize = (uint) buffer.Capacity; + } else { + throw new InvalidOperationException (string.Format ( + CultureInfo.CurrentCulture, "Service {0} was not" + + " found on computer '{1}'.", serviceName, + machineName), new Win32Exception ()); + } + } else { + return buffer.ToString (); + } + } + } + + private static string GetServiceName (IntPtr scHandle, string displayName) + { + StringBuilder buffer = new StringBuilder (); + + uint bufferSize = (uint) buffer.Capacity; + + while (true) { + if (!GetServiceKeyName (scHandle, displayName, buffer, ref bufferSize)) { + int err = Marshal.GetLastWin32Error (); + if (err == ERROR_INSUFFICIENT_BUFFER) { + // allocate additional byte for terminating null char + buffer = new StringBuilder ((int) bufferSize + 1); + bufferSize = (uint) buffer.Capacity; + } else { + throw new Win32Exception (); + } + } else { + return buffer.ToString (); + } + } + } + + private static SERVICE_STATUS_PROCESS GetServiceStatus (string serviceName, string machineName) + { + IntPtr scHandle = IntPtr.Zero; + IntPtr svcHandle = IntPtr.Zero; + IntPtr buffer = IntPtr.Zero; + + try { + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); + + svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_QUERY_STATUS); + if (svcHandle == IntPtr.Zero) + throw CreateCannotOpenServiceException (serviceName, machineName); + + int bufferSize = 0; + int bytesNeeded = 0; + + while (true) { + if (!QueryServiceStatusEx (svcHandle, SC_STATUS_PROCESS_INFO, buffer, bufferSize, out bytesNeeded)) { + int err = Marshal.GetLastWin32Error (); + if (err == ERROR_INSUFFICIENT_BUFFER) { + buffer = Marshal.AllocHGlobal (bytesNeeded); + bufferSize = bytesNeeded; + } else { + throw new Win32Exception (err); + } + } else { + SERVICE_STATUS_PROCESS serviceStatus = (SERVICE_STATUS_PROCESS) Marshal.PtrToStructure ( + buffer, typeof (SERVICE_STATUS_PROCESS)); + return serviceStatus; + } + } + } finally { + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + if (svcHandle != IntPtr.Zero) + CloseServiceHandle (svcHandle); + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal (buffer); + } + } + + private static ServiceController [] GetServices (string machineName, SERVICE_TYPE serviceType, string group) + { + IntPtr scHandle = IntPtr.Zero; + IntPtr buffer = IntPtr.Zero; + + try { +#if NET_2_0 + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_ENUMERATE_SERVICE); +#else + scHandle = OpenServiceControlManager (machineName, + SERVICE_MANAGER_RIGHTS.SC_MANAGER_ENUMERATE_SERVICE, true); +#endif + + uint bufferSize = 0; + uint bytesNeeded = 0; + uint servicesReturned = 0; + uint resumeHandle = 0; + + ServiceController [] services; + + while (true) { + if (!EnumServicesStatusEx (scHandle, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_REQUEST.SERVICE_STATE_ALL, buffer, bufferSize, out bytesNeeded, out servicesReturned, ref resumeHandle, group)) { + int err = Marshal.GetLastWin32Error (); + if (err == ERROR_MORE_DATA) { + buffer = Marshal.AllocHGlobal ((int) bytesNeeded); + bufferSize = bytesNeeded; + } else { + throw new Win32Exception (err); + } + } else { + int iPtr = buffer.ToInt32 (); + + services = new ServiceController [servicesReturned]; + for (int i = 0; i < servicesReturned; i++) { + ENUM_SERVICE_STATUS_PROCESS serviceStatus = (ENUM_SERVICE_STATUS_PROCESS) Marshal.PtrToStructure ( + new IntPtr (iPtr), typeof (ENUM_SERVICE_STATUS_PROCESS)); + // TODO: use internal ctor that takes displayname too + services [i] = new ServiceController (serviceStatus.pServiceName, + machineName); + // move on to the next services + iPtr += ENUM_SERVICE_STATUS_PROCESS.SizeOf; + } + + // we're done, so exit the loop + break; + } + } + + return services; + } finally { + if (scHandle != IntPtr.Zero) + CloseServiceHandle (scHandle); + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal (buffer); + } + } + + private static IntPtr OpenServiceControlManager (string machineName, SERVICE_MANAGER_RIGHTS rights) + { + return OpenServiceControlManager (machineName, rights, false); + } + + private static IntPtr OpenServiceControlManager (string machineName, SERVICE_MANAGER_RIGHTS rights, bool ignoreWin32Error) + { + IntPtr scHandle = OpenSCManager (machineName, SERVICES_ACTIVE_DATABASE, + rights); + if (scHandle == IntPtr.Zero) { + string msg = string.Format (CultureInfo.CurrentCulture, + "Cannot open Service Control Manager on computer '{0}'." + + " This operation might require other priviliges.", + machineName); + if (ignoreWin32Error) + throw new InvalidOperationException (msg); + throw new InvalidOperationException (msg, new Win32Exception ()); + } + return scHandle; + } + + private static InvalidOperationException CreateCannotOpenServiceException (string serviceName, string machineName) + { + return new InvalidOperationException (string.Format (CultureInfo.CurrentCulture, + "Cannot open {0} service on computer '{1}'.", serviceName, machineName), + new Win32Exception ()); + } + + #region PInvoke declaration + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern void CloseServiceHandle (IntPtr SCHANDLE); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool ControlService ( + IntPtr hService, + SERVICE_CONTROL_TYPE dwControl, + ref SERVICE_STATUS lpServiceStatus); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool EnumDependentServices ( + IntPtr hService, + SERVICE_STATE_REQUEST dwServiceState, + IntPtr lpServices, + uint cbBufSize, + out uint pcbBytesNeeded, + out uint lpServicesReturned); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool EnumServicesStatusEx ( + IntPtr hSCManager, + int InfoLevel, + SERVICE_TYPE dwServiceType, + SERVICE_STATE_REQUEST dwServiceState, + IntPtr lpServices, + uint cbBufSize, + out uint pcbBytesNeeded, + out uint lpServicesReturned, + ref uint lpResumeHandle, + string pszGroupName); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool GetServiceDisplayName ( + IntPtr hSCManager, + string lpServiceName, + StringBuilder lpDisplayName, + ref uint lpcchBuffer); + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool GetServiceKeyName ( + IntPtr hSCManager, + string lpDisplayName, + StringBuilder lpServiceName, + ref uint lpcchBuffer); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern IntPtr OpenSCManager ( + string lpMachineName, + string lpSCDB, + SERVICE_MANAGER_RIGHTS scParameter); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern IntPtr OpenService ( + IntPtr SCHANDLE, + string lpSvcName, + SERVICE_RIGHTS dwNumServiceArgs); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool QueryServiceConfig ( + IntPtr hService, + IntPtr lpServiceConfig, + uint cbBufSize, + out uint pcbBytesNeeded); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool QueryServiceStatusEx ( + IntPtr serviceHandle, + int InfoLevel, + IntPtr lpBuffer, + int cbBufSize, + out int pcbBytesNeeded); + + [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool StartService ( + IntPtr SVHANDLE, + int dwNumServiceArgs, + IntPtr [] lpServiceArgVectors); + + private const int SC_ENUM_PROCESS_INFO = 0; + private const char SC_GROUP_IDENTIFIER = '+'; + private const int SC_STATUS_PROCESS_INFO = 0; + private const int SERVICE_NO_CHANGE = -1; + private const int ERROR_MORE_DATA = 234; + private const int ERROR_INSUFFICIENT_BUFFER = 122; + private const int STANDARD_RIGHTS_REQUIRED = 0xf0000; + private const string SERVICES_ACTIVE_DATABASE = "ServicesActive"; + + internal struct QUERY_SERVICE_CONFIG + { + public int dwServiceType; + public int dwStartType; + public int dwErrorControl; + public IntPtr lpBinaryPathName; + public IntPtr lpLoadOrderGroup; + public int dwTagId; + public IntPtr lpDependencies; + public IntPtr lpServiceStartName; + public IntPtr lpDisplayName; + } + + [Flags] + private enum SERVICE_RIGHTS + { + SERVICE_QUERY_CONFIG = 1, + SERVICE_CHANGE_CONFIG = 2, + SERVICE_QUERY_STATUS = 4, + SERVICE_ENUMERATE_DEPENDENTS = 8, + SERVICE_START = 16, + SERVICE_STOP = 32, + SERVICE_PAUSE_CONTINUE = 64, + SERVICE_INTERROGATE = 128, + SERVICE_USER_DEFINED_CONTROL = 256, + SERVICE_ALL_ACCESS = (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) + } + + private enum SERVICE_MANAGER_RIGHTS : uint + { + STANDARD_RIGHTS_READ = 0x20000, + STANDARD_RIGHTS_WRITE = 0x20000, + STANDARD_RIGHTS_EXECUTE = 0x20000, + STANDARD_RIGHTS_ALL = 0x1F0000, + + SC_MANAGER_ALL_ACCESS = 0xf003f, + SC_MANAGER_CONNECT = 1, + SC_MANAGER_CREATE_SERVICE = 2, + SC_MANAGER_ENUMERATE_SERVICE = 4, + SC_MANAGER_LOCK = 8, + SC_MANAGER_QUERY_LOCK_STATUS = 16, + SC_MANAGER_MODIFY_BOOT_CONFIG = 32, + + GENERIC_READ = 0x80000000, + GENERIC_WRITE = 0x40000000, + GENERIC_EXECUTE = 0x20000000, + GENERIC_ALL = 0x10000000 + } + + [StructLayout (LayoutKind.Sequential)] + private struct ENUM_SERVICE_STATUS_PROCESS + { + public static readonly int SizeOf = Marshal.SizeOf (typeof (ENUM_SERVICE_STATUS_PROCESS)); + + [MarshalAs (UnmanagedType.LPWStr)] + public string pServiceName; + + [MarshalAs (UnmanagedType.LPWStr)] + public string pDisplayName; + + public SERVICE_STATUS_PROCESS ServiceStatus; + } + + [StructLayout (LayoutKind.Sequential)] + private struct ENUM_SERVICE_STATUS + { + public static readonly int SizeOf = Marshal.SizeOf (typeof (ENUM_SERVICE_STATUS)); + + [MarshalAs (UnmanagedType.LPWStr)] + public string pServiceName; + [MarshalAs (UnmanagedType.LPWStr)] + public string pDisplayName; + public SERVICE_STATUS ServiceStatus; + } + + [StructLayout (LayoutKind.Sequential)] + private struct SERVICE_STATUS + { + public ServiceType dwServiceType; + public ServiceControllerStatus dwCurrentState; + public SERVICE_CONTROL_ACCEPTED dwControlsAccepted; + public int dwWin32ExitCode; + public int dwServiceSpecificExitCode; + public uint dwCheckPoint; + public uint dwWaitHint; + } + + [StructLayout (LayoutKind.Sequential, Pack = 1)] + private struct SERVICE_STATUS_PROCESS + { + public static readonly int SizeOf = Marshal.SizeOf (typeof (SERVICE_STATUS_PROCESS)); + + public ServiceType dwServiceType; + public ServiceControllerStatus dwCurrentState; + public SERVICE_CONTROL_ACCEPTED dwControlsAccepted; + public int dwWin32ExitCode; + public int dwServiceSpecificExitCode; + public int dwCheckPoint; + public int dwWaitHint; + public int dwProcessId; + public int dwServiceFlags; + } + + private enum SERVICE_TYPE + { + SERVICE_KERNEL_DRIVER = 0x1, + SERVICE_FILE_SYSTEM_DRIVER = 0x2, + SERVICE_ADAPTER = 0x4, + SERVICE_RECOGNIZER_DRIVER = 0x8, + SERVICE_DRIVER = (SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER), + SERVICE_WIN32_OWN_PROCESS = 0x10, + SERVICE_WIN32_SHARE_PROCESS = 0x20, + SERVICE_INTERACTIVE_PROCESS = 0x100, + SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE, + SERVICE_WIN32 = (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS), + SERVICE_TYPE_ALL = (SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS) + } + + private enum SERVICE_START_TYPE + { + SERVICE_BOOT_START = 0x0, + SERVICE_SYSTEM_START = 0x1, + SERVICE_AUTO_START = 0x2, + SERVICE_DEMAND_START = 0x3, + SERVICE_DISABLED = 0x4, + SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE + } + + private enum SERVICE_ERROR_CONTROL + { + SERVICE_ERROR_IGNORE = 0x0, + SERVICE_ERROR_NORMAL = 0x1, + SERVICE_ERROR_SEVERE = 0x2, + SERVICE_ERROR_CRITICAL = 0x3, + msidbServiceInstallErrorControlVital = 0x8000, + SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE + } + + private enum SERVICE_STATE_REQUEST + { + SERVICE_ACTIVE = 0x1, + SERVICE_INACTIVE = 0x2, + SERVICE_STATE_ALL = (SERVICE_ACTIVE | SERVICE_INACTIVE) + } + + private enum SERVICE_CONTROL_TYPE + { + SERVICE_CONTROL_STOP = 0x1, + SERVICE_CONTROL_PAUSE = 0x2, + SERVICE_CONTROL_CONTINUE = 0x3, + SERVICE_CONTROL_INTERROGATE = 0x4, + SERVICE_CONTROL_SHUTDOWN = 0x5, + SERVICE_CONTROL_PARAMCHANGE = 0x6, + SERVICE_CONTROL_NETBINDADD = 0x7, + SERVICE_CONTROL_NETBINDREMOVE = 0x8, + SERVICE_CONTROL_NETBINDENABLE = 0x9, + SERVICE_CONTROL_NETBINDDISABLE = 0xA, + SERVICE_CONTROL_DEVICEEVENT = 0xB, + SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0xC, + SERVICE_CONTROL_POWEREVENT = 0xD, + SERVICE_CONTROL_SESSIONCHANGE = 0xE + } + + [Flags] + private enum SERVICE_CONTROL_ACCEPTED + { + SERVICE_ACCEPT_NONE = 0x0, + SERVICE_ACCEPT_STOP = 0x1, + SERVICE_ACCEPT_PAUSE_CONTINUE = 0x2, + SERVICE_ACCEPT_SHUTDOWN = 0x4, + SERVICE_ACCEPT_PARAMCHANGE = 0x8, + SERVICE_ACCEPT_NETBINDCHANGE = 0x10, + SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x20, + SERVICE_ACCEPT_POWEREVENT = 0x40, + SERVICE_ACCEPT_SESSIONCHANGE = 0x80 + } + + #endregion PInvoke declaration + } +} diff --git a/mcs/class/System.ServiceProcess/System.ServiceProcess_test.dll.sources b/mcs/class/System.ServiceProcess/System.ServiceProcess_test.dll.sources index 291d412454f..51c26fff79a 100644 --- a/mcs/class/System.ServiceProcess/System.ServiceProcess_test.dll.sources +++ b/mcs/class/System.ServiceProcess/System.ServiceProcess_test.dll.sources @@ -1,2 +1,3 @@ +System.ServiceProcess/ServiceControllerTest.cs System.ServiceProcess/ServiceControllerPermissionAttributeTest.cs System.ServiceProcess/ServiceControllerPermissionTest.cs diff --git a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ChangeLog b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ChangeLog index d48efbd611a..5ffa1572d12 100644 --- a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ChangeLog +++ b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ChangeLog @@ -1,3 +1,12 @@ +2006-09-14 Gert Driesen <drieseng@users.sourceforge.net> + + * ServiceControllerPermissionTest.cs: Set eol-style to native. Fixed + warning and improved Union_Null test. + * ServiceControllerPermissionAttributeTest.cs: Set eol-style to native. + Fixed warning. + * ServiceControllerTest.cs: Added unit tests for win32 implementation + of ServiceController. + 2005-09-22 Sebastien Pouliot <sebastien@ximian.com> * ServiceControllerPermissionAttributeTest.cs: Removed *Choice diff --git a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionAttributeTest.cs b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionAttributeTest.cs index 289388489df..1b2d4d957b6 100644 --- a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionAttributeTest.cs +++ b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionAttributeTest.cs @@ -77,7 +77,7 @@ namespace MonoTests.System.ServiceProcess { [Test] public void Action_Invalid () { - ServiceControllerPermissionAttribute a = new ServiceControllerPermissionAttribute ((SecurityAction)Int32.MinValue); + new ServiceControllerPermissionAttribute ((SecurityAction)Int32.MinValue); // no validation in attribute } diff --git a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionTest.cs b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionTest.cs index 72790de7c97..68666c883a5 100644 --- a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionTest.cs +++ b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerPermissionTest.cs @@ -278,7 +278,7 @@ namespace MonoTests.System.ServiceProcess { scp.PermissionEntries.Add (new ServiceControllerPermissionEntry (ServiceControllerPermissionAccess.None, "localhost", "http")); // Union with null is a simple copy ServiceControllerPermission union = (ServiceControllerPermission)scp.Union (null); - Assert.IsNotNull (scp.PermissionEntries.Count, "Count"); + Assert.AreEqual (1, union.PermissionEntries.Count, "Count"); } [Test] diff --git a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerTest.cs b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerTest.cs new file mode 100644 index 00000000000..58ecf47228d --- /dev/null +++ b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceControllerTest.cs @@ -0,0 +1,4970 @@ +// +// ServiceControllerTest.cs - +// NUnit Test Cases for ServiceController +// +// Author: +// Gert Driesen (drieseng@users.sourceforge.net) +// +// Copyright (C) 2006 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// TODO: +// - Status +// - Start + +using System; +using System.ComponentModel; +using System.ServiceProcess; +using TimeoutException = System.ServiceProcess.TimeoutException; + +using NUnit.Framework; + +namespace MonoTests.System.ServiceProcess +{ + [TestFixture] + public class ServiceControllerTest + { + [Test] + public void Constructor1 () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + + try { + bool value = sc.CanPauseAndContinue; + Assert.Fail ("#A1: " + value.ToString ()); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2"); + Assert.IsNotNull (ex.Message, "#A3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#A4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#A5"); + Assert.IsNull (ex.ParamName, "#A6"); + Assert.IsNull (ex.InnerException, "#A7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2"); + Assert.IsNotNull (ex.Message, "#A3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#A4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#A5"); + Assert.IsNotNull (ex.InnerException, "#A6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#A7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#A8"); + Assert.IsNotNull (win32Error.Message, "#A9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#A10"); + Assert.IsNull (win32Error.InnerException, "#A11"); + } +#endif + + try { + bool value = sc.CanShutdown; + Assert.Fail ("#B1: " + value.ToString ()); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#B5"); + Assert.IsNull (ex.ParamName, "#B6"); + Assert.IsNull (ex.InnerException, "#B7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } +#endif + + try { + bool value = sc.CanStop; + Assert.Fail ("#C1: " + value.ToString ()); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#C5"); + Assert.IsNull (ex.ParamName, "#C6"); + Assert.IsNull (ex.InnerException, "#C7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } +#endif + + // closing the ServiceController does not result in exception + sc.Close (); + + try { + sc.Continue (); + Assert.Fail ("#D1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#D5"); + Assert.IsNull (ex.ParamName, "#D6"); + Assert.IsNull (ex.InnerException, "#D7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } +#endif + + try { + Assert.Fail ("#E1: " + sc.DependentServices.Length); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#E2"); + Assert.IsNotNull (ex.Message, "#E3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#E4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#E5"); + Assert.IsNull (ex.ParamName, "#E6"); + Assert.IsNull (ex.InnerException, "#E7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#E2"); + Assert.IsNotNull (ex.Message, "#E3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#E4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#E5"); + Assert.IsNotNull (ex.InnerException, "#E6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#E7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#E8"); + Assert.IsNotNull (win32Error.Message, "#E9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#E10"); + Assert.IsNull (win32Error.InnerException, "#E11"); + } +#endif + + Assert.IsNotNull (sc.DisplayName, "#F1"); + Assert.AreEqual (string.Empty, sc.DisplayName, "#F2"); + + try { + sc.ExecuteCommand (0); + Assert.Fail ("#G1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#G2"); + Assert.IsNotNull (ex.Message, "#G3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#G4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#G5"); + Assert.IsNull (ex.ParamName, "#G6"); + Assert.IsNull (ex.InnerException, "#G7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#G2"); + Assert.IsNotNull (ex.Message, "#G3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#G4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#G5"); + Assert.IsNotNull (ex.InnerException, "#G6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#G7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#G8"); + Assert.IsNotNull (win32Error.Message, "#G9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#G10"); + Assert.IsNull (win32Error.InnerException, "#G11"); + } +#endif + + Assert.IsNotNull (sc.MachineName, "#H1"); + Assert.AreEqual (".", sc.MachineName, "#H2"); + + + try { + sc.Pause (); + Assert.Fail ("#I1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#I2"); + Assert.IsNotNull (ex.Message, "#I3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#I4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#I5"); + Assert.IsNull (ex.ParamName, "#I6"); + Assert.IsNull (ex.InnerException, "#I7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#I2"); + Assert.IsNotNull (ex.Message, "#I3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#I4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#I5"); + Assert.IsNotNull (ex.InnerException, "#I6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#I7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#I8"); + Assert.IsNotNull (win32Error.Message, "#I9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#I10"); + Assert.IsNull (win32Error.InnerException, "#I11"); + } +#endif + } + + [Test] + public void Constructor2 () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("lanmanworkstation"); + + Assert.IsTrue (sc.CanPauseAndContinue, "#A1"); + Assert.IsTrue (sc.CanShutdown, "#B1"); + Assert.IsTrue (sc.CanStop, "#C1"); + + sc.Close (); + sc.Continue (); + + ServiceController [] dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#D1"); + Assert.IsTrue (dependentServices.Length > 1, "#D2"); + + Assert.IsNotNull (sc.DisplayName, "#E1"); + Assert.AreEqual ("Workstation", sc.DisplayName, "#E2"); + + Assert.IsNotNull (sc.MachineName, "#F1"); + Assert.AreEqual (".", sc.MachineName, "#F2"); + + sc.Refresh (); + + Assert.IsNotNull (sc.ServiceName, "#G1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#G2"); + + ServiceController [] servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#H1"); + Assert.AreEqual (0, servicesDependedOn.Length, "#H2"); + + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#I1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#J1"); + } + + [Test] + public void Constructor2_Name_Empty () + { + try { + new ServiceController (string.Empty); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // Invalid value for parameter name + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("name") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void Constructor2_Name_DisplayName () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("workstation"); + + Assert.IsTrue (sc.CanPauseAndContinue, "#A1"); + Assert.IsTrue (sc.CanShutdown, "#B1"); + Assert.IsTrue (sc.CanStop, "#C1"); + } + + [Test] + public void Constructor2_Name_Null () + { + try { + new ServiceController (null); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // Invalid value for parameter name + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("name") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void Constructor2_Name_ServiceName () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("lanmanworkstation"); + + Assert.IsTrue (sc.CanPauseAndContinue, "#A1"); + Assert.IsTrue (sc.CanShutdown, "#B1"); + Assert.IsTrue (sc.CanStop, "#C1"); + } + + [Test] + public void Constructor3 () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("lanmanworkstation", + Environment.MachineName); + + Assert.IsTrue (sc.CanPauseAndContinue, "#A1"); + Assert.IsTrue (sc.CanShutdown, "#B1"); + Assert.IsTrue (sc.CanStop, "#C1"); + + sc.Close (); + sc.Continue (); + + ServiceController [] dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#D1"); + Assert.IsTrue (dependentServices.Length > 1, "#D2"); + + Assert.IsNotNull (sc.DisplayName, "#E1"); + Assert.AreEqual ("Workstation", sc.DisplayName, "#E2"); + + Assert.IsNotNull (sc.MachineName, "#F1"); + Assert.AreEqual (Environment.MachineName, sc.MachineName, "#F2"); + + sc.Refresh (); + + Assert.IsNotNull (sc.ServiceName, "#G1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#G2"); + + ServiceController [] servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#H1"); + Assert.AreEqual (0, servicesDependedOn.Length, "#H2"); + + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#I1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#J1"); + } + + [Test] + public void Constructor3_MachineName_Empty () + { + try { + new ServiceController ("alerter", string.Empty); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void Constructor3_MachineName_Null () + { + try { + new ServiceController ("alerter", null); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void Constructor3_Name_Empty () + { + try { + new ServiceController (string.Empty, "."); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // Invalid value for parameter name + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("name") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void Constructor3_Name_Null () + { + try { + new ServiceController (null, "."); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // Invalid value for parameter name + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("name") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void CanPauseAndContinue () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.IsTrue (sc.CanPauseAndContinue, "#1"); + sc.ServiceName = "SamSs"; + Assert.IsFalse (sc.CanPauseAndContinue, "#2"); + sc.DisplayName = "Workstation"; + Assert.IsTrue (sc.CanPauseAndContinue, "#3"); + sc.MachineName = "doesnotexist"; + try { + bool value = sc.CanPauseAndContinue; + Assert.Fail ("#4: " + value.ToString ()); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#5"); + Assert.IsNotNull (ex.Message, "#6"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#7"); + Assert.IsNotNull (ex.InnerException, "#8"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#9"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#10"); + Assert.IsNotNull (win32Error.Message, "#11"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#12"); + Assert.IsNull (win32Error.InnerException, "#13"); + } + } + + [Test] + public void CanPauseAndContinue_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + bool canPauseAndContinue = sc.CanPauseAndContinue; + Assert.Fail ("#1: " + canPauseAndContinue); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void CanPauseAndContinue_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("NetDDE", "."); + Assert.IsFalse (sc1.CanPauseAndContinue); + } + + [Test] + public void CanPauseAndContinue_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + bool canPauseAndContinue = sc.CanPauseAndContinue; + Assert.Fail ("#1: " + canPauseAndContinue); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void CanPauseAndContinue_Service_OperationNotValid () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("SamSs", "."); + Assert.IsFalse (sc1.CanPauseAndContinue); + } + + [Test] + public void CanPauseAndContinue_Service_Running () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#1"); + Assert.IsTrue (sc.CanPauseAndContinue, "#2"); + } + + [Test] + public void CanPauseAndContinue_Service_Paused () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + Assert.IsTrue (sc1.CanPauseAndContinue, "#B1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#B2"); + + sc1.Pause (); + + try { + Assert.IsTrue (sc1.CanPauseAndContinue, "#C1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.IsTrue (sc1.CanPauseAndContinue, "#D1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#D2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.IsTrue (sc1.CanPauseAndContinue, "#E1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#E2"); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void CanPauseAndContinue_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + Assert.IsTrue (sc1.CanPauseAndContinue, "#B1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#B2"); + + sc1.Stop (); + + try { + Assert.IsTrue (sc1.CanPauseAndContinue, "#C1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.IsFalse (sc1.CanPauseAndContinue, "#D1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#D2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.IsTrue (sc1.CanPauseAndContinue, "#E1"); + Assert.IsTrue (sc2.CanPauseAndContinue, "#E2"); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void CanPauseAndContinue_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + bool canPauseAndContinue = sc.CanPauseAndContinue; + Assert.Fail ("#1: " + canPauseAndContinue); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void CanShutdown () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.IsTrue (sc.CanShutdown, "#1"); + sc.ServiceName = "SamSs"; + Assert.IsFalse (sc.CanShutdown, "#2"); + sc.DisplayName = "Workstation"; + Assert.IsTrue (sc.CanShutdown, "#3"); + sc.MachineName = "doesnotexist"; + try { + bool value = sc.CanShutdown; + Assert.Fail ("#4: " + value.ToString ()); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#5"); + Assert.IsNotNull (ex.Message, "#6"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#7"); + Assert.IsNotNull (ex.InnerException, "#8"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#9"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#10"); + Assert.IsNotNull (win32Error.Message, "#11"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#12"); + Assert.IsNull (win32Error.InnerException, "#13"); + } + } + + [Test] + public void CanShutdown_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + bool canShutdown = sc.CanShutdown; + Assert.Fail ("#1: " + canShutdown); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void CanShutdown_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("NetDDE", "."); + Assert.IsFalse (sc1.CanShutdown); + } + + [Test] + public void CanShutdown_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + bool value = sc.CanShutdown; + Assert.Fail ("#1: " + value.ToString ()); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void CanShutdown_Service_OperationNotValid () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("SamSs", "."); + Assert.IsFalse (sc1.CanShutdown); + } + + [Test] + public void CanShutdown_Service_Running () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#1"); + Assert.IsTrue (sc.CanShutdown, "#2"); + } + + [Test] + public void CanShutdown_Service_Paused () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + Assert.IsTrue (sc1.CanShutdown, "#B1"); + Assert.IsTrue (sc2.CanShutdown, "#B2"); + + sc1.Pause (); + + try { + Assert.IsTrue (sc1.CanShutdown, "#C1"); + Assert.IsTrue (sc2.CanShutdown, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.IsTrue (sc1.CanShutdown, "#D1"); + Assert.IsTrue (sc2.CanShutdown, "#D2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.IsTrue (sc1.CanShutdown, "#E1"); + Assert.IsTrue (sc2.CanShutdown, "#E2"); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void CanShutdown_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + Assert.IsTrue (sc1.CanShutdown, "#B1"); + Assert.IsTrue (sc2.CanShutdown, "#B2"); + + sc1.Stop (); + + try { + Assert.IsTrue (sc1.CanShutdown, "#C1"); + Assert.IsTrue (sc2.CanShutdown, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.IsFalse (sc1.CanShutdown, "#D1"); + Assert.IsTrue (sc2.CanShutdown, "#D2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.IsTrue (sc1.CanShutdown, "#E1"); + Assert.IsTrue (sc2.CanShutdown, "#E2"); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void CanShutdown_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + bool canShutdown = sc.CanShutdown; + Assert.Fail ("#1: " + canShutdown); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void CanStop () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.IsTrue (sc.CanStop, "#1"); + sc.ServiceName = "SamSs"; + Assert.IsFalse (sc.CanStop, "#2"); + sc.DisplayName = "Workstation"; + Assert.IsTrue (sc.CanStop, "#3"); + sc.MachineName = "doesnotexist"; + try { + bool value = sc.CanStop; + Assert.Fail ("#4: " + value.ToString ()); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#5"); + Assert.IsNotNull (ex.Message, "#6"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#7"); + Assert.IsNotNull (ex.InnerException, "#8"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#9"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#10"); + Assert.IsNotNull (win32Error.Message, "#11"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#12"); + Assert.IsNull (win32Error.InnerException, "#13"); + } + } + + [Test] + public void CanStop_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + bool canStop = sc.CanStop; + Assert.Fail ("#1: " + canStop); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void CanStop_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("NetDDE", "."); + Assert.IsFalse (sc1.CanStop); + } + + [Test] + public void CanStop_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + bool canStop = sc.CanStop; + Assert.Fail ("#1: " + canStop); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void CanStop_Service_OperationNotValid () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("SamSs", "."); + Assert.IsFalse (sc1.CanStop); + } + + [Test] + public void CanStop_Service_Running () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#1"); + Assert.IsTrue (sc.CanStop, "#2"); + } + + [Test] + public void CanStop_Service_Paused () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + Assert.IsTrue (sc1.CanStop, "#B1"); + Assert.IsTrue (sc2.CanStop, "#B2"); + + sc1.Pause (); + + try { + Assert.IsTrue (sc1.CanStop, "#C1"); + Assert.IsTrue (sc2.CanStop, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.IsTrue (sc1.CanStop, "#D1"); + Assert.IsTrue (sc2.CanStop, "#D2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.IsTrue (sc1.CanStop, "#E1"); + Assert.IsTrue (sc2.CanStop, "#E2"); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void CanStop_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + Assert.IsTrue (sc1.CanStop, "#B1"); + Assert.IsTrue (sc2.CanStop, "#B2"); + + sc1.Stop (); + + try { + Assert.IsTrue (sc1.CanStop, "#C1"); + Assert.IsTrue (sc2.CanStop, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.IsFalse (sc1.CanStop, "#D1"); + Assert.IsTrue (sc2.CanStop, "#D2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.IsTrue (sc1.CanShutdown, "#E1"); + Assert.IsTrue (sc2.CanShutdown, "#E2"); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void CanStop_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + bool canStop = sc.CanStop; + Assert.Fail ("#1: " + canStop); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void Continue () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Pause (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.Continue (); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + + sc1.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#E2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + } + + [Test] + public void Continue_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + sc.Continue (); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void Continue_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("NetDDE", "."); + ServiceController sc2 = new ServiceController ("NetDDE", "."); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2"); + + try { + sc1.Continue (); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot resume NetDDE service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("NetDDE") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The service has not been started + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (1062, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#C2"); + } + + [Test] + public void Continue_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + sc.Continue (); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void Continue_Service_OperationNotValid () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("SamSs", "."); + ServiceController sc2 = new ServiceController ("SamSs", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + try { + sc1.Continue (); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot resume SamSs service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("SamSs") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The requested control is not valid for this service + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (1052, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + } + + [Test] + public void Continue_Service_Running () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Continue (); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + } + + [Test] + public void Continue_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Stop (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.Continue (); + Assert.Fail ("#D1"); + } catch (InvalidOperationException ex) { + // Cannot resume Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The service has not been started + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (1062, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#E2"); + } + + [Test] + public void Continue_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + sc.Continue (); + Assert.Fail ("#1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void DependentServices () + { + if (RunningOnUnix) + return; + + ServiceController sc = null; + ServiceController [] dependentServices = null; + + // single dependent service + sc = new ServiceController ("dmserver", "."); + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#A1"); + Assert.AreEqual (1, dependentServices.Length, "#A2"); + Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#A3"); + + // MSBUG: modifying ServiceName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.ServiceName = "alerter"; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#B1"); + Assert.AreEqual (1, dependentServices.Length, "#B2"); + Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#B3"); + + // MSBUG: modifying DisplayName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.DisplayName = "Spooler"; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#C1"); + Assert.AreEqual (1, dependentServices.Length, "#C2"); + Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#C3"); + + // MSBUG: modifying MachineName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.MachineName = "doesnotexist"; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#D1"); + Assert.AreEqual (1, dependentServices.Length, "#D2"); + Assert.AreEqual ("dmadmin", dependentServices [0].ServiceName, "#D3"); + + // no dependent services + sc = new ServiceController ("alerter", "."); + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#E1"); + Assert.AreEqual (0, dependentServices.Length, "#E2"); + + // MSBUG: modifying ServiceName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.ServiceName = "dmserver"; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#F1"); + Assert.AreEqual (0, dependentServices.Length, "#F2"); + + // MSBUG: modifying DisplayName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.DisplayName = "Workstation"; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#G1"); + Assert.AreEqual (0, dependentServices.Length, "#G2"); + + // MSBUG: modifying MachineName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.MachineName = Environment.MachineName; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#H1"); + Assert.AreEqual (0, dependentServices.Length, "#H2"); + + // multiple dependent services + sc = new ServiceController ("TapiSrv", "."); + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#I1"); + Assert.AreEqual (2, dependentServices.Length, "#I2"); + Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#I3"); + Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#I4"); + + // MSBUG: modifying ServiceName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.ServiceName = "spooler"; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#J1"); + Assert.AreEqual (2, dependentServices.Length, "#J3"); + Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#J4"); + Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#J5"); + + // MSBUG: modifying DisplayName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.DisplayName = "Alerter"; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#K1"); + Assert.AreEqual (2, dependentServices.Length, "#K2"); + Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#K3"); + Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#K4"); + + // MSBUG: modifying MachineName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.MachineName = Environment.MachineName; + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#L1"); + Assert.AreEqual (2, dependentServices.Length, "#L2"); + Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#L3"); + Assert.AreEqual ("RasMan", dependentServices [1].ServiceName, "#L4"); + } + + [Test] + public void DependentServices_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("dmserver", + "doesnotexist"); + try { + ServiceController [] dependenServices = sc.DependentServices; + Assert.Fail ("#1: " + dependenServices.Length); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void DependentServices_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("NetDDE", "."); + ServiceController [] dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#1"); + Assert.AreEqual (1, dependentServices.Length, "#2"); + Assert.AreEqual ("ClipSrv", dependentServices [0].ServiceName, "#3"); + } + + [Test] + public void DependentServices_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + ServiceController [] dependenServices = sc.DependentServices; + Assert.Fail ("#1: " + dependenServices.Length); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void DependentServices_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + ServiceController [] dependenServices = sc.DependentServices; + Assert.Fail ("#1: " + dependenServices.Length); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void DisplayName () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.DisplayName = "workstation"; + Assert.AreEqual ("workstation", sc.DisplayName, "#A1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2"); + + sc.DisplayName = "alerter"; + Assert.AreEqual ("alerter", sc.DisplayName, "#B1"); + Assert.AreEqual ("Alerter", sc.ServiceName, "#B2"); + + sc = new ServiceController ("workstation"); + sc.DisplayName = "alerter"; + Assert.AreEqual ("alerter", sc.DisplayName, "#C1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#C2"); + Assert.AreEqual ("workstation", sc.DisplayName, "#C3"); + + sc.DisplayName = "alerter"; + Assert.AreEqual ("alerter", sc.DisplayName, "#D1"); + Assert.AreEqual ("Alerter", sc.ServiceName, "#D2"); + + sc.DisplayName = "workstation"; + Assert.AreEqual ("workstation", sc.DisplayName, "#E1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#E2"); + + sc = new ServiceController ("workstation"); + Assert.AreEqual ("workstation", sc.DisplayName, "#F1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#F2"); + + sc.DisplayName = "Workstation"; + Assert.AreEqual ("Workstation", sc.DisplayName, "#G1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#G2"); + } + + [Test] + public void DisplayName_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("dmserver", + "doesnotexist"); + try { + string displayName = sc.DisplayName; + Assert.Fail ("#1: " + displayName); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void DisplayName_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("NetDDE", "."); + Assert.AreEqual ("Network DDE", sc.DisplayName); + } + + [Test] + public void DisplayName_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + string displayName = sc.DisplayName; + Assert.Fail ("#1: " + displayName); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void DisplayName_ServiceName_Empty () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.DisplayName = "workstation"; + Assert.AreEqual ("workstation", sc.DisplayName, "#A1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2"); + } + + [Test] + public void DisplayName_Value_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.DisplayName = "doesnotexist"; + Assert.AreEqual ("doesnotexist", sc.DisplayName, "#1"); + try { + string serviceName = sc.ServiceName; + Assert.Fail ("#2: " + serviceName); + } catch (InvalidOperationException ex) { + // Service doesnotexist was not found on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#3"); + Assert.IsNotNull (ex.Message, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#5"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#6"); + Assert.IsNotNull (ex.InnerException, "#7"); + + // The specified service does not exist as an installed service + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#8"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#9"); + Assert.IsNotNull (win32Error.Message, "#10"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#11"); + Assert.IsNull (win32Error.InnerException, "#12"); + } + Assert.AreEqual ("doesnotexist", sc.DisplayName, "#13"); + } + + [Test] + public void DisplayName_Value_Empty () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + Assert.AreEqual (string.Empty, sc.DisplayName, "#A1"); + Assert.AreEqual (string.Empty, sc.ServiceName, "#A2"); + + sc.DisplayName = "WorkStation"; + + Assert.AreEqual ("WorkStation", sc.DisplayName, "#B1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#B2"); + + sc.DisplayName = string.Empty; + + Assert.AreEqual (string.Empty, sc.DisplayName, "#C1"); + Assert.AreEqual (string.Empty, sc.ServiceName, "#C2"); + } + + [Test] + public void DisplayName_Value_Null () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.DisplayName = "Alerter"; + try { + sc.DisplayName = null; + Assert.Fail ("#1"); + } catch (ArgumentNullException ex) { + Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsNotNull (ex.ParamName, "#4"); + Assert.AreEqual ("value", ex.ParamName, "#5"); + Assert.IsNull (ex.InnerException, "#6"); + } + Assert.AreEqual ("Alerter", sc.DisplayName, "#7"); + } + + [Test] + public void DisplayName_Value_ServiceName () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.DisplayName = "lanmanworkstation"; + Assert.AreEqual ("lanmanworkstation", sc.DisplayName, "#A1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2"); + Assert.AreEqual ("Workstation", sc.DisplayName, "#A3"); + } + + [Test] + public void ExecuteCommand_Device_ControlCodes () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Disk", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + try { + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_CONTINUE); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_DEVICEEVENT); + Assert.Fail ("#C1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_HARDWAREPROFILECHANGE); + Assert.Fail ("#D1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_INTERROGATE); + Assert.Fail ("#E1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#E2"); + Assert.IsNotNull (ex.Message, "#E3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#E4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#E5"); + Assert.IsNotNull (ex.InnerException, "#E6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#E7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#E8"); + Assert.IsNotNull (win32Error.Message, "#E9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#E10"); + Assert.IsNull (win32Error.InnerException, "#E11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDADD); + Assert.Fail ("#F1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#F2"); + Assert.IsNotNull (ex.Message, "#F3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#F4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#F5"); + Assert.IsNotNull (ex.InnerException, "#F6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#F7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#F8"); + Assert.IsNotNull (win32Error.Message, "#F9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#F10"); + Assert.IsNull (win32Error.InnerException, "#F11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDDISABLE); + Assert.Fail ("#G1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#G2"); + Assert.IsNotNull (ex.Message, "#G3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#G4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#G5"); + Assert.IsNotNull (ex.InnerException, "#G6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#G7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#G8"); + Assert.IsNotNull (win32Error.Message, "#G9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#G10"); + Assert.IsNull (win32Error.InnerException, "#G11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDENABLE); + Assert.Fail ("#H1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#H2"); + Assert.IsNotNull (ex.Message, "#H3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#H4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#H5"); + Assert.IsNotNull (ex.InnerException, "#H6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#H7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#H8"); + Assert.IsNotNull (win32Error.Message, "#H9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#H10"); + Assert.IsNull (win32Error.InnerException, "#H11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDREMOVE); + Assert.Fail ("#I1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#I2"); + Assert.IsNotNull (ex.Message, "#I3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#I4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#I5"); + Assert.IsNotNull (ex.InnerException, "#I6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#I7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#I8"); + Assert.IsNotNull (win32Error.Message, "#I9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#I10"); + Assert.IsNull (win32Error.InnerException, "#I11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PARAMCHANGE); + Assert.Fail ("#J1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#J2"); + Assert.IsNotNull (ex.Message, "#J3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#J4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#J5"); + Assert.IsNotNull (ex.InnerException, "#J6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#J7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#J8"); + Assert.IsNotNull (win32Error.Message, "#J9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#J10"); + Assert.IsNull (win32Error.InnerException, "#J11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE); + Assert.Fail ("#K1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#K2"); + Assert.IsNotNull (ex.Message, "#K3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#K4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#K5"); + Assert.IsNotNull (ex.InnerException, "#K6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#K7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#K8"); + Assert.IsNotNull (win32Error.Message, "#K9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#K10"); + Assert.IsNull (win32Error.InnerException, "#K11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_POWEREVENT); + Assert.Fail ("#L1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#L2"); + Assert.IsNotNull (ex.Message, "#L3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#L4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#L5"); + Assert.IsNotNull (ex.InnerException, "#L6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#L7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#L8"); + Assert.IsNotNull (win32Error.Message, "#L9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#L10"); + Assert.IsNull (win32Error.InnerException, "#L11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SESSIONCHANGE); + Assert.Fail ("#M1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#M2"); + Assert.IsNotNull (ex.Message, "#M3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#M4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#M5"); + Assert.IsNotNull (ex.InnerException, "#M6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#M7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#M8"); + Assert.IsNotNull (win32Error.Message, "#M9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#M10"); + Assert.IsNull (win32Error.InnerException, "#M11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SHUTDOWN); + Assert.Fail ("#N1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#N2"); + Assert.IsNotNull (ex.Message, "#N3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#N4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#N5"); + Assert.IsNotNull (ex.InnerException, "#N6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#N7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#N8"); + Assert.IsNotNull (win32Error.Message, "#N9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#N10"); + Assert.IsNull (win32Error.InnerException, "#N11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_STOP); + Assert.Fail ("#O1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#O2"); + Assert.IsNotNull (ex.Message, "#O3"); + Assert.IsTrue (ex.Message.IndexOf ("Disk") != -1, "#O4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#O5"); + Assert.IsNotNull (ex.InnerException, "#O6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#O7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#O8"); + Assert.IsNotNull (win32Error.Message, "#O9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#O10"); + Assert.IsNull (win32Error.InnerException, "#O11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#P"); + } + + [Test] + public void ExecuteCommand_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void ExecuteCommand_Parameter_Incorrect () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + try { + try { + sc.ExecuteCommand (127); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + sc.ExecuteCommand (128); + sc.ExecuteCommand (255); + + try { + sc.ExecuteCommand (256); + Assert.Fail ("#C1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#D"); + } + + [Test] + public void ExecuteCommand_Service_ContinuePending () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + sc.Pause (); + + try { + sc.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + Assert.AreEqual (ServiceControllerStatus.Paused, sc.Status, "#B"); + + sc.Continue (); + + sc.ExecuteCommand (128); + + try { + sc.ExecuteCommand (127); + Assert.Fail ("#C1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#E"); + } + + [Test] + public void ExecuteCommand_Service_ControlCodes () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + try { + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_CONTINUE); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_DEVICEEVENT); + Assert.Fail ("#C1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_HARDWAREPROFILECHANGE); + Assert.Fail ("#D1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_INTERROGATE); + Assert.Fail ("#E1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#E2"); + Assert.IsNotNull (ex.Message, "#E3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#E4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#E5"); + Assert.IsNotNull (ex.InnerException, "#E6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#E7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#E8"); + Assert.IsNotNull (win32Error.Message, "#E9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#E10"); + Assert.IsNull (win32Error.InnerException, "#E11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDADD); + Assert.Fail ("#F1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#F2"); + Assert.IsNotNull (ex.Message, "#F3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#F4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#F5"); + Assert.IsNotNull (ex.InnerException, "#F6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#F7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#F8"); + Assert.IsNotNull (win32Error.Message, "#F9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#F10"); + Assert.IsNull (win32Error.InnerException, "#F11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDDISABLE); + Assert.Fail ("#G1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#G2"); + Assert.IsNotNull (ex.Message, "#G3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#G4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#G5"); + Assert.IsNotNull (ex.InnerException, "#G6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#G7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#G8"); + Assert.IsNotNull (win32Error.Message, "#G9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#G10"); + Assert.IsNull (win32Error.InnerException, "#G11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDENABLE); + Assert.Fail ("#H1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#H2"); + Assert.IsNotNull (ex.Message, "#H3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#H4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#H5"); + Assert.IsNotNull (ex.InnerException, "#H6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#H7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#H8"); + Assert.IsNotNull (win32Error.Message, "#H9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#H10"); + Assert.IsNull (win32Error.InnerException, "#H11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_NETBINDREMOVE); + Assert.Fail ("#I1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#I2"); + Assert.IsNotNull (ex.Message, "#I3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#I4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#I5"); + Assert.IsNotNull (ex.InnerException, "#I6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#I7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#I8"); + Assert.IsNotNull (win32Error.Message, "#I9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#I10"); + Assert.IsNull (win32Error.InnerException, "#I11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PARAMCHANGE); + Assert.Fail ("#J1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#J2"); + Assert.IsNotNull (ex.Message, "#J3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#J4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#J5"); + Assert.IsNotNull (ex.InnerException, "#J6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#J7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#J8"); + Assert.IsNotNull (win32Error.Message, "#J9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#J10"); + Assert.IsNull (win32Error.InnerException, "#J11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE); + Assert.Fail ("#K1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#K2"); + Assert.IsNotNull (ex.Message, "#K3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#K4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#K5"); + Assert.IsNotNull (ex.InnerException, "#K6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#K7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#K8"); + Assert.IsNotNull (win32Error.Message, "#K9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#K10"); + Assert.IsNull (win32Error.InnerException, "#K11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_POWEREVENT); + Assert.Fail ("#L1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#L2"); + Assert.IsNotNull (ex.Message, "#L3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#L4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#L5"); + Assert.IsNotNull (ex.InnerException, "#L6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#L7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#L8"); + Assert.IsNotNull (win32Error.Message, "#L9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#L10"); + Assert.IsNull (win32Error.InnerException, "#L11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SESSIONCHANGE); + Assert.Fail ("#M1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#M2"); + Assert.IsNotNull (ex.Message, "#M3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#M4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#M5"); + Assert.IsNotNull (ex.InnerException, "#M6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#M7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#M8"); + Assert.IsNotNull (win32Error.Message, "#M9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#M10"); + Assert.IsNull (win32Error.InnerException, "#M11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_SHUTDOWN); + Assert.Fail ("#N1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#N2"); + Assert.IsNotNull (ex.Message, "#N3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#N4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#N5"); + Assert.IsNotNull (ex.InnerException, "#N6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#N7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#N8"); + Assert.IsNotNull (win32Error.Message, "#N9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#N10"); + Assert.IsNull (win32Error.InnerException, "#N11"); + } + + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_STOP); + Assert.Fail ("#O1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#O2"); + Assert.IsNotNull (ex.Message, "#O3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#O4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#O5"); + Assert.IsNotNull (ex.InnerException, "#O6"); + + // Access is denied + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#O7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#O8"); + Assert.IsNotNull (win32Error.Message, "#O9"); + Assert.AreEqual (5, win32Error.NativeErrorCode, "#O10"); + Assert.IsNull (win32Error.InnerException, "#O11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#P"); + } + + [Test] + public void ExecuteCommand_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_INTERROGATE); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void ExecuteCommand_Service_Paused () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + sc.Pause (); + + try { + sc.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + Assert.AreEqual (ServiceControllerStatus.Paused, sc.Status, "#B"); + sc.ExecuteCommand (154); + sc.Refresh (); + Assert.AreEqual (ServiceControllerStatus.Paused, sc.Status, "#C"); + //sc.ExecuteCommand (127); + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#D"); + } + + [Test] + public void ExecuteCommand_Service_PausePending () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + sc.Pause (); + + try { + sc.ExecuteCommand (128); + + try { + sc.ExecuteCommand (127); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#C"); + } + + [Test] + public void ExecuteCommand_Service_StartPending () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + sc.Stop (); + + try { + sc.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc.Status, "#B"); + + sc.Start (); + + try { + sc.ExecuteCommand (127); + Assert.Fail ("#C1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } + + try { + sc.ExecuteCommand (128); + Assert.Fail ("#D1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The service cannot accept control messages at this time + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (1061, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#D"); + } + + [Test] + public void ExecuteCommand_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + sc.Stop (); + + try { + sc.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc.Status, "#B"); + + try { + sc.ExecuteCommand (127); + Assert.Fail ("#C1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } + + try { + sc.ExecuteCommand (128); + Assert.Fail ("#D1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The service has not been started + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (1062, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#E"); + } + + [Test] + public void ExecuteCommand_Service_StopPending () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", "."); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A"); + + sc.Stop (); + + try { + try { + sc.ExecuteCommand (127); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The parameter is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (87, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + try { + sc.ExecuteCommand (128); + Assert.Fail ("#C1"); + } catch (InvalidOperationException ex) { + // Cannot control Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); + Assert.IsNotNull (ex.Message, "#C3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#C4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5"); + Assert.IsNotNull (ex.InnerException, "#C6"); + + // The service cannot accept control messages at this time + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8"); + Assert.IsNotNull (win32Error.Message, "#C9"); + Assert.AreEqual (1061, win32Error.NativeErrorCode, "#C10"); + Assert.IsNull (win32Error.InnerException, "#C11"); + } + } finally { + EnsureServiceIsRunning (sc); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#D"); + } + + [Test] + public void ExecuteCommand_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_INTERROGATE); + Assert.Fail ("#1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void GetDevices () + { + if (RunningOnUnix) + return; + + ServiceController [] devices = null; + + devices = ServiceController.GetDevices (); + Assert.IsNotNull (devices, "#A1"); + + bool foundDisk = false; + bool foundAlerter = false; + + foreach (ServiceController sc in devices) { + switch (sc.ServiceName) { + case "Disk": + Assert.AreEqual ("Disk Driver", sc.DisplayName, "#A2"); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#A3"); + foundDisk = true; + break; + case "Alerter": + foundAlerter = true; + break; + } + } + + Assert.IsTrue (foundDisk, "#A4"); + Assert.IsFalse (foundAlerter, "#A5"); + + devices = ServiceController.GetDevices (Environment.MachineName); + Assert.IsNotNull (devices, "#B1"); + + foundDisk = false; + foundAlerter = false; + + foreach (ServiceController sc in devices) { + switch (sc.ServiceName) { + case "Disk": + Assert.AreEqual ("Disk Driver", sc.DisplayName, "#B2"); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#B3"); + foundDisk = true; + break; + case "Alerter": + foundAlerter = true; + break; + } + } + + Assert.IsTrue (foundDisk, "#B4"); + Assert.IsFalse (foundAlerter, "#B5"); + } + + [Test] + public void GetDevices_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + try { + ServiceController [] devices = ServiceController.GetDevices ("doesnotexist"); + Assert.Fail ("#1: " + devices.Length); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); +#if ONLY_1_1 + Assert.IsNull (ex.InnerException, "#5"); +#else + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); +#endif + } + } + + [Test] + public void GetDevices_MachineName_Empty () + { + try { + ServiceController.GetDevices (string.Empty); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void GetDevices_MachineName_Null () + { + try { + ServiceController.GetDevices (null); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void GetServices () + { + if (RunningOnUnix) + return; + + ServiceController [] services = null; + + services = ServiceController.GetServices (); + Assert.IsNotNull (services, "#A1"); + + bool foundDisk = false; + bool foundWorkstation = false; + + foreach (ServiceController sc in services) { + switch (sc.ServiceName) { + case "Disk": + foundDisk = true; + break; + case "lanmanworkstation": + foundWorkstation = true; + break; + } + } + + Assert.IsFalse (foundDisk, "#A4"); + Assert.IsTrue (foundWorkstation, "#A5"); + + services = ServiceController.GetServices (Environment.MachineName); + Assert.IsNotNull (services, "#B1"); + + foundDisk = false; + foundWorkstation = false; + + foreach (ServiceController sc in services) { + switch (sc.ServiceName) { + case "Disk": + foundDisk = true; + break; + case "lanmanworkstation": + Assert.AreEqual ("Workstation", sc.DisplayName, "#B2"); + Assert.AreEqual (ServiceControllerStatus.Running, sc.Status, "#B3"); + foundWorkstation = true; + break; + } + } + + Assert.IsFalse (foundDisk, "#B4"); + Assert.IsTrue (foundWorkstation, "#B5"); + } + + [Test] + public void GetServices_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + try { + ServiceController [] services = ServiceController.GetServices ("doesnotexist"); + Assert.Fail ("#1: " + services.Length); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); +#if ONLY_1_1 + Assert.IsNull (ex.InnerException, "#5"); +#else + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); +#endif + } + } + + [Test] + public void GetServices_MachineName_Empty () + { + try { + ServiceController.GetServices (string.Empty); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void GetServices_MachineName_Null () + { + try { + ServiceController.GetServices (null); + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + } + + [Test] + public void MachineName () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.ServiceName = "alerter"; + Assert.AreEqual ("Alerter", sc.DisplayName, "#A1"); + Assert.AreEqual (".", sc.MachineName, "#A2"); + Assert.AreEqual ("alerter", sc.ServiceName, "#A3"); + + sc.MachineName = Environment.MachineName; + Assert.AreEqual ("Alerter", sc.DisplayName, "#B1"); + Assert.AreEqual (Environment.MachineName, sc.MachineName, "#B2"); + Assert.AreEqual ("alerter", sc.ServiceName, "#B3"); + + sc.MachineName = "doesnotexist"; + Assert.AreEqual ("Alerter", sc.DisplayName, "#C1"); + Assert.AreEqual ("doesnotexist", sc.MachineName, "#C2"); + Assert.AreEqual ("alerter", sc.ServiceName, "#C3"); + + sc.MachineName = "DoesNotExist"; + Assert.AreEqual ("Alerter", sc.DisplayName, "#D1"); + Assert.AreEqual ("DoesNotExist", sc.MachineName, "#D2"); + Assert.AreEqual ("alerter", sc.ServiceName, "#D3"); + } + + [Test] + public void MachineName_Empty () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.MachineName = Environment.MachineName; + try { + sc.MachineName = string.Empty; + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + Assert.AreEqual (Environment.MachineName, sc.MachineName, "#8"); + } + + [Test] + public void MachineName_Null () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.MachineName = Environment.MachineName; + try { + sc.MachineName = null; + Assert.Fail ("#1"); + } catch (ArgumentException ex) { + // MachineName value is invalid + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("MachineName") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } + Assert.AreEqual (Environment.MachineName, sc.MachineName, "#8"); + } + + [Test] + public void Pause () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Pause (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + } + + [Test] + public void Pause_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + sc.Pause (); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void Pause_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("NetDDE", "."); + ServiceController sc2 = new ServiceController ("NetDDE", "."); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2"); + + try { + sc1.Pause (); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot pause NetDDE service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("NetDDE") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The service has not been started + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (1062, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#C2"); + } + + [Test] + public void Pause_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + sc.Pause (); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void Pause_Service_OperationNotValid () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("SamSs", "."); + ServiceController sc2 = new ServiceController ("SamSs", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + try { + sc1.Pause (); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot pause SamSs service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("SamSs") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The requested control is not valid for this service + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (1052, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + } + + [Test] + public void Pause_Service_Paused () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Pause (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.Pause (); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#E2"); + } + + [Test] + public void Pause_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Stop (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.Pause (); + Assert.Fail ("#D1"); + } catch (InvalidOperationException ex) { + // Cannot pause Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The service has not been started + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (1062, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#E2"); + } + + [Test] + public void Pause_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + sc.Pause (); + Assert.Fail ("#1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void Refresh () + { + if (RunningOnUnix) + return; + + ServiceController sc = null; + ServiceController [] dependentServices = null; + ServiceController [] servicesDependedOn = null; + + sc = new ServiceController ("NetDDE", "."); + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#A1"); + Assert.AreEqual (1, dependentServices.Length, "#A2"); + Assert.AreEqual ("ClipSrv", dependentServices [0].ServiceName, "#A3"); + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#A4"); + Assert.AreEqual (1, servicesDependedOn.Length, "#A5"); + Assert.AreEqual ("NetDDEDSDM", servicesDependedOn [0].ServiceName, "#A6"); + + sc.ServiceName = "rasman"; + sc.Refresh (); + + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#B1"); + Assert.AreEqual (1, dependentServices.Length, "#B2"); + Assert.AreEqual ("RasAuto", dependentServices [0].ServiceName, "#B3"); + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#B4"); + Assert.AreEqual (1, servicesDependedOn.Length, "#B5"); + Assert.AreEqual ("Tapisrv", servicesDependedOn [0].ServiceName, "#B6"); + + sc.DisplayName = "NetDDE"; + sc.Refresh (); + + dependentServices = sc.DependentServices; + Assert.IsNotNull (dependentServices, "#C1"); + Assert.AreEqual (1, dependentServices.Length, "#C2"); + Assert.AreEqual ("ClipSrv", dependentServices [0].ServiceName, "#C3"); + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#C4"); + Assert.AreEqual (1, servicesDependedOn.Length, "#C5"); + Assert.AreEqual ("NetDDEDSDM", servicesDependedOn [0].ServiceName, "#C6"); + } + + [Test] + public void Refresh_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + sc.Refresh (); + } + + [Test] + public void Refresh_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + sc.Refresh (); + } + + [Test] + public void Refresh_Service_Paused () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Pause (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.Refresh (); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + + sc2.Refresh (); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Paused, sc2.Status, "#E2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void Refresh_Service_Running () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Stop (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + sc2.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#C2"); + + sc1.Start (); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#D2"); + + sc1.Refresh (); + + Assert.AreEqual (ServiceControllerStatus.StartPending, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#E2"); + + sc1.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#F2"); + + sc2.Refresh (); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#G1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#G2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#H1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#H2"); + } + + [Test] + public void Refresh_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Stop (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + + sc2.Refresh (); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#E2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void Refresh_ServiceName_Empty () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.Refresh (); + } + + [Test] + public void ServiceName () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.ServiceName = "lanmanworkstation"; + Assert.AreEqual ("Workstation", sc.DisplayName, "#A1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#A2"); + + sc.ServiceName = "alerter"; + Assert.AreEqual ("Alerter", sc.DisplayName, "#B1"); + Assert.AreEqual ("alerter", sc.ServiceName, "#B2"); + + sc = new ServiceController ("lanmanworkstation"); + sc.ServiceName = "alerter"; + Assert.AreEqual ("alerter", sc.ServiceName, "#C1"); + Assert.AreEqual ("Alerter", sc.DisplayName, "#C2"); + Assert.AreEqual ("Alerter", sc.DisplayName, "#C3"); + + sc.ServiceName = "alerter"; + Assert.AreEqual ("alerter", sc.ServiceName, "#D1"); + Assert.AreEqual ("Alerter", sc.DisplayName, "#D2"); + + sc.ServiceName = "lanmanworkstation"; + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#E1"); + Assert.AreEqual ("Workstation", sc.DisplayName, "#E2"); + + sc = new ServiceController ("lanmanWorkstation"); + Assert.AreEqual ("lanmanWorkstation", sc.ServiceName, "#F1"); + Assert.AreEqual ("Workstation", sc.DisplayName, "#F2"); + + sc.ServiceName = "LanManWorkstation"; + Assert.AreEqual ("LanManWorkstation", sc.ServiceName, "#G1"); + Assert.AreEqual ("Workstation", sc.DisplayName, "#G2"); + } + + [Test] + public void ServiceName_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("dmserver", + "doesnotexist"); + try { + string serviceName = sc.ServiceName; + Assert.Fail ("#1: " + serviceName); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void ServiceName_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("NetDDE", "."); + Assert.AreEqual ("NetDDE", sc.ServiceName); + } + + [Test] + public void ServiceName_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + string serviceName = sc.ServiceName; + Assert.Fail ("#1: " + serviceName); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void ServiceName_DisplayName_Empty () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.ServiceName = "lanmanworkstation"; + Assert.AreEqual ("Workstation", sc.DisplayName, "#1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#2"); + } + + [Test] + public void ServiceName_Value_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.ServiceName = "doesnotexist"; + try { + string displayName = sc.DisplayName; + Assert.Fail ("#1: " + displayName); + } catch (InvalidOperationException ex) { + // Service doesnotexist was not found on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The specified service does not exist as an installed service + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + Assert.AreEqual ("doesnotexist", sc.ServiceName, "#12"); + } + + [Test] + public void ServiceName_Value_Empty () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + Assert.AreEqual (string.Empty, sc.DisplayName, "#A1"); + Assert.AreEqual (string.Empty, sc.ServiceName, "#A2"); + + sc.ServiceName = "lanmanworkstation"; + + Assert.AreEqual ("Workstation", sc.DisplayName, "#B1"); + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#B2"); + +#if ONLY_1_1 + sc.ServiceName = string.Empty; + + Assert.AreEqual (string.Empty, sc.DisplayName, "#C1"); + Assert.AreEqual (string.Empty, sc.ServiceName, "#C2"); +#else + try { + sc.ServiceName = string.Empty; + Assert.Fail ("#C1"); + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2"); + Assert.IsNotNull (ex.Message, "#A3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#A4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#A5"); + Assert.IsNull (ex.ParamName, "#A6"); + Assert.IsNull (ex.InnerException, "#A7"); + } +#endif + } + + [Test] + public void ServiceName_Value_Null () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.ServiceName = "lanmanworkstation"; + try { + sc.ServiceName = null; + Assert.Fail ("#1"); + } catch (ArgumentNullException ex) { + Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsNotNull (ex.ParamName, "#4"); + Assert.AreEqual ("value", ex.ParamName, "#5"); + Assert.IsNull (ex.InnerException, "#6"); + } + + Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#7"); + } + + [Test] + public void ServiceName_Value_DisplayName () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController (); + sc.ServiceName = "workstation"; + try { + string displayName = sc.DisplayName; + Assert.Fail ("#1: " + displayName); + } catch (InvalidOperationException ex) { + // Display name could not be retrieved for service workstation + // on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("workstation") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The specified service does not exist as an installed service + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + Assert.AreEqual ("workstation", sc.ServiceName, "#12"); + } + + [Test] + public void ServicesDependedOn () + { + if (RunningOnUnix) + return; + + ServiceController sc = null; + ServiceController [] servicesDependedOn = null; + + // single depended service + sc = new ServiceController ("spooler", "."); + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#A1"); + Assert.AreEqual (1, servicesDependedOn.Length, "#A2"); + Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#A3"); + + // MSBUG: modifying ServiceName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.ServiceName = "lanmanworkstation"; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#B1"); + Assert.AreEqual (1, servicesDependedOn.Length, "#B2"); + Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#B3"); + + // MSBUG: modifying DisplayName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.DisplayName = "alerter"; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#C1"); + Assert.AreEqual (1, servicesDependedOn.Length, "#C2"); + Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#C3"); + + // MSBUG: modifying MachineName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.MachineName = "doesnotexist"; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#D1"); + Assert.AreEqual (1, servicesDependedOn.Length, "#D2"); + Assert.AreEqual ("RPCSS", servicesDependedOn [0].ServiceName, "#D3"); + + // no depended services + sc = new ServiceController ("lanmanworkstation", "."); + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#E1"); + Assert.AreEqual (0, servicesDependedOn.Length, "#E2"); + + // MSBUG: modifying ServiceName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.ServiceName = "spooler"; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#F1"); + Assert.AreEqual (0, servicesDependedOn.Length, "#F2"); + + // MSBUG: modifying DisplayName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.DisplayName = "Alerter"; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#G1"); + Assert.AreEqual (0, servicesDependedOn.Length, "#G2"); + + // MSBUG: modifying MachineName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.MachineName = Environment.MachineName; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#H1"); + Assert.AreEqual (0, servicesDependedOn.Length, "#H2"); + + // multiple depended services + sc = new ServiceController ("dmadmin", "."); + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#I1"); + Assert.AreEqual (3, servicesDependedOn.Length, "#I2"); + // do not rely on the order of the services + Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#I3"); + Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#I4"); + Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#I5"); + + // MSBUG: modifying ServiceName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.ServiceName = "spooler"; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#J1"); + Assert.AreEqual (3, servicesDependedOn.Length, "#J2"); + // do not rely on the order of the services + Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#J3"); + Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#J4"); + Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#J5"); + + // MSBUG: modifying DisplayName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.DisplayName = "Alerter"; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#K1"); + Assert.AreEqual (3, servicesDependedOn.Length, "#K2"); + // do not rely on the order of the services + Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#K3"); + Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#K4"); + Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#K5"); + + // MSBUG: modifying MachineName does not cause cache to be cleared + // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=201762 + sc.MachineName = Environment.MachineName; + servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#L1"); + Assert.AreEqual (3, servicesDependedOn.Length, "#L2"); + // do not rely on the order of the services + Assert.IsTrue (ContainsService (servicesDependedOn, "RpcSs"), "#L3"); + Assert.IsTrue (ContainsService (servicesDependedOn, "PlugPlay"), "#L4"); + Assert.IsTrue (ContainsService (servicesDependedOn, "DmServer"), "#L5"); + } + + [Test] + public void ServicesDependedOn_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("dmserver", + "doesnotexist"); + try { + ServiceController [] servicesDependedOn = sc.ServicesDependedOn; + Assert.Fail ("#1: " + servicesDependedOn.Length); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void ServicesDependedOn_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("ClipSrv", "."); + ServiceController [] servicesDependedOn = sc.ServicesDependedOn; + Assert.IsNotNull (servicesDependedOn, "#1"); + Assert.AreEqual (1, servicesDependedOn.Length, "#2"); + Assert.AreEqual ("NetDDE", servicesDependedOn [0].ServiceName, "#3"); + } + + [Test] + public void ServicesDependedOn_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + ServiceController [] servicesDependedOn = sc.ServicesDependedOn; + Assert.Fail ("#1: " + servicesDependedOn.Length); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void ServicesDependedOn_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + ServiceController [] servicesDependedOn = sc.ServicesDependedOn; + Assert.Fail ("#1: " + servicesDependedOn.Length); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void ServiceTypeTest () + { + if (RunningOnUnix) + return; + + ServiceController sc = null; + + sc = new ServiceController ("dmserver", "."); + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#A1"); + sc.ServiceName = "Disk"; + Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#A2"); + sc.DisplayName = "Workstation"; + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#A3"); + sc.MachineName = "doesnotexist"; + try { + ServiceType serviceType = sc.ServiceType; + Assert.Fail ("#A4: " + serviceType); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A5"); + Assert.IsNotNull (ex.Message, "#A6"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#A7"); + Assert.IsNotNull (ex.InnerException, "#A8"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#A9"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#A10"); + Assert.IsNotNull (win32Error.Message, "#A11"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#A12"); + Assert.IsNull (win32Error.InnerException, "#A13"); + } + + sc = new ServiceController ("Disk", "."); + Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#B1"); + sc.DisplayName = "Alerter"; + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#B2"); + sc.MachineName = Environment.MachineName; + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#B3"); + sc.ServiceName = "Disk"; + Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#B4"); + } + + [Test] + public void ServiceType_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("dmserver", + "doesnotexist"); + try { + ServiceType serviceType = sc.ServiceType; + Assert.Fail ("#1: " + serviceType); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void ServiceType_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("NetDDE", "."); + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType); + } + + [Test] + public void ServiceType_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + ServiceType serviceType = sc.ServiceType; + Assert.Fail ("#1: " + serviceType); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void ServiceType_ServiceName_Empty () + { + if (RunningOnUnix) + return; + + ServiceController sc = null; + + sc = new ServiceController (); + sc.DisplayName = "workstation"; + Assert.AreEqual (ServiceType.Win32ShareProcess, sc.ServiceType, "#1"); + + sc = new ServiceController (); + sc.DisplayName = "disk driver"; + Assert.AreEqual (ServiceType.KernelDriver, sc.ServiceType, "#2"); + } + + [Test] + public void Start () + { + // not sure if we need additional tests for this, as it's actually + // tested as part of the other unit tests + } + + [Test] + public void Status () + { + // not sure if we need additional tests for this, as it's actually + // tested as part of the other unit tests + } + + [Test] + public void Stop () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Stop (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + } + + [Test] + public void Stop_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + sc.Stop (); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void Stop_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("NetDDE", "."); + ServiceController sc2 = new ServiceController ("NetDDE", "."); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2"); + + try { + sc1.Stop (); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot stop NetDDE service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("NetDDE") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The service has not been started + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (1062, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#C2"); + } + + [Test] + public void Stop_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + sc.Stop (); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void Stop_Service_OperationNotValid () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("SamSs", "."); + ServiceController sc2 = new ServiceController ("SamSs", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + try { + sc1.Stop (); + Assert.Fail ("#B1"); + } catch (InvalidOperationException ex) { + // Cannot stop SamSs service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); + Assert.IsNotNull (ex.Message, "#B3"); + Assert.IsTrue (ex.Message.IndexOf ("SamSs") != -1, "#B4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5"); + Assert.IsNotNull (ex.InnerException, "#B6"); + + // The requested control is not valid for this service + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8"); + Assert.IsNotNull (win32Error.Message, "#B9"); + Assert.AreEqual (1052, win32Error.NativeErrorCode, "#B10"); + Assert.IsNull (win32Error.InnerException, "#B11"); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + } + + [Test] + public void Stop_Service_Paused () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Pause (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.Stop (); + + Assert.AreEqual (ServiceControllerStatus.Paused, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#E2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void Stop_Service_Stopped () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Stop (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.Stop (); + Assert.Fail ("#D1"); + } catch (InvalidOperationException ex) { + // Cannot stop Schedule service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2"); + Assert.IsNotNull (ex.Message, "#D3"); + Assert.IsTrue (ex.Message.IndexOf ("Schedule") != -1, "#D4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5"); + Assert.IsNotNull (ex.InnerException, "#D6"); + + // The service has not been started + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8"); + Assert.IsNotNull (win32Error.Message, "#D9"); + Assert.AreEqual (1062, win32Error.NativeErrorCode, "#D10"); + Assert.IsNull (win32Error.InnerException, "#D11"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#E2"); + } + + [Test] + public void Stop_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + sc.Stop (); + Assert.Fail ("#1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void WaitForStatus () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.Stop (); + + try { + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#B1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#B2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + + sc1.Start (); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#D1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#D2"); + + sc1.WaitForStatus (ServiceControllerStatus.Running); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#E1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#E2"); + } finally { + EnsureServiceIsRunning (sc1); + sc2.Refresh (); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#F1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#F2"); + } + + [Test] + public void WaitForStatus_Machine_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("Schedule", + "doesnotexist"); + try { + sc.WaitForStatus (ServiceControllerStatus.Stopped, + new TimeSpan (0, 0, 1)); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open Service Control Manager on computer 'doesnotexist'. + // This operation might require other priviliges + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4"); + Assert.IsNotNull (ex.InnerException, "#5"); + + // The RPC server is unavailable + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#6"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#7"); + Assert.IsNotNull (win32Error.Message, "#8"); + Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9"); + Assert.IsNull (win32Error.InnerException, "#10"); + } + } + + [Test] + public void WaitForStatus_Service_Disabled () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("NetDDE", "."); + ServiceController sc2 = new ServiceController ("NetDDE", "."); + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#A2"); + + sc1.WaitForStatus (ServiceControllerStatus.Stopped, + new TimeSpan (0, 0, 1)); + + try { + sc1.WaitForStatus (ServiceControllerStatus.Running, + new TimeSpan (0, 0, 1)); + Assert.Fail ("#B1"); + } catch (TimeoutException ex) { + // Time out has expired and the operation has not been completed + Assert.AreEqual (typeof (TimeoutException), ex.GetType (), "#B2"); +#if NET_2_0 + Assert.IsNotNull (ex.Data, "#B3"); + Assert.AreEqual (0, ex.Data.Count, "#B4"); +#endif + Assert.IsNotNull (ex.Message, "#B5"); + Assert.IsNull (ex.InnerException, "#B6"); + } + + Assert.AreEqual (ServiceControllerStatus.Stopped, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Stopped, sc2.Status, "#C2"); + } + + [Test] + public void WaitForStatus_Service_DoesNotExist () + { + if (RunningOnUnix) + return; + + ServiceController sc = new ServiceController ("doesnotexist", "."); + try { + sc.WaitForStatus (ServiceControllerStatus.Stopped); + Assert.Fail ("#1"); + } catch (InvalidOperationException ex) { + // Cannot open doesnotexist service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf ("doesnotexist") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (1060, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } + } + + [Test] + public void WaitForStatus_Service_OperationNotValid () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("SamSs", "."); + ServiceController sc2 = new ServiceController ("SamSs", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + sc1.WaitForStatus (ServiceControllerStatus.Running, + new TimeSpan (0, 0, 1)); + + try { + sc1.WaitForStatus (ServiceControllerStatus.Stopped, + new TimeSpan (0, 0, 1)); + Assert.Fail ("#B1"); + } catch (TimeoutException ex) { + // Time out has expired and the operation has not been completed + Assert.AreEqual (typeof (TimeoutException), ex.GetType (), "#B2"); +#if NET_2_0 + Assert.IsNotNull (ex.Data, "#B3"); + Assert.AreEqual (0, ex.Data.Count, "#B4"); +#endif + Assert.IsNotNull (ex.Message, "#B5"); + Assert.IsNull (ex.InnerException, "#B6"); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + } + + [Test] + public void WaitForStatus_ServiceName_Empty () + { +#if ONLY_1_1 + if (RunningOnUnix) + return; +#endif + + ServiceController sc = new ServiceController (); + try { + sc.WaitForStatus (ServiceControllerStatus.Stopped, + new TimeSpan (0, 0, 1)); + Assert.Fail ("#1"); +#if NET_2_0 + } catch (ArgumentException ex) { + // Service name contains invalid characters, is empty or is + // too long (max length = 80) + Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("80") != -1, "#5"); + Assert.IsNull (ex.ParamName, "#6"); + Assert.IsNull (ex.InnerException, "#7"); + } +#else + } catch (InvalidOperationException ex) { + // Cannot open service on computer '.' + Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); + Assert.IsNotNull (ex.Message, "#3"); + Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4"); + Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5"); + Assert.IsNotNull (ex.InnerException, "#6"); + + // The filename, directory name, or volume label is incorrect + Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7"); + Win32Exception win32Error = (Win32Exception) ex.InnerException; + //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8"); + Assert.IsNotNull (win32Error.Message, "#9"); + Assert.AreEqual (123, win32Error.NativeErrorCode, "#10"); + Assert.IsNull (win32Error.InnerException, "#11"); + } +#endif + } + + [Test] + public void WaitForStatus_Timeout () + { + if (RunningOnUnix) + return; + + ServiceController sc1 = new ServiceController ("Schedule", "."); + ServiceController sc2 = new ServiceController ("Schedule", "."); + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#A1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#A2"); + + try { + sc1.WaitForStatus (ServiceControllerStatus.Stopped, + new TimeSpan (0, 0, 1)); + Assert.Fail ("#B1"); + } catch (TimeoutException ex) { + // Time out has expired and the operation has not been completed + Assert.AreEqual (typeof (TimeoutException), ex.GetType (), "#B2"); +#if NET_2_0 + Assert.IsNotNull (ex.Data, "#B3"); + Assert.AreEqual (0, ex.Data.Count, "#B4"); +#endif + Assert.IsNotNull (ex.Message, "#B5"); + Assert.IsNull (ex.InnerException, "#B6"); + } + + Assert.AreEqual (ServiceControllerStatus.Running, sc1.Status, "#C1"); + Assert.AreEqual (ServiceControllerStatus.Running, sc2.Status, "#C2"); + } + + private static void EnsureServiceIsRunning (ServiceController sc) + { + sc.Refresh (); + switch (sc.Status) { + case ServiceControllerStatus.ContinuePending: + sc.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + break; + case ServiceControllerStatus.Paused: + sc.Continue (); + sc.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + break; + case ServiceControllerStatus.PausePending: + sc.WaitForStatus (ServiceControllerStatus.Paused, new TimeSpan (0, 0, 5)); + sc.Continue (); + sc.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + break; + case ServiceControllerStatus.StartPending: + sc.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + break; + case ServiceControllerStatus.Stopped: + sc.Start (); + sc.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + break; + case ServiceControllerStatus.StopPending: + sc.WaitForStatus (ServiceControllerStatus.Stopped, new TimeSpan (0, 0, 5)); + sc.Start (); + sc.WaitForStatus (ServiceControllerStatus.Running, new TimeSpan (0, 0, 5)); + break; + } + } + + private static bool ContainsService (ServiceController [] services, string serviceName) + { + for (int i = 0; i < services.Length; i++) { + if (services [i].ServiceName == serviceName) + return true; + } + return false; + } + + private bool RunningOnUnix + { + get { +#if NET_2_0 + return Environment.OSVersion.Platform == PlatformID.Unix; +#else + int p = (int) Environment.OSVersion.Platform; + return ((p == 4) || (p == 128)); +#endif + } + } + + private enum SERVICE_CONTROL_TYPE + { + SERVICE_CONTROL_STOP = 0x1, + SERVICE_CONTROL_PAUSE = 0x2, + SERVICE_CONTROL_CONTINUE = 0x3, + SERVICE_CONTROL_INTERROGATE = 0x4, + SERVICE_CONTROL_SHUTDOWN = 0x5, + SERVICE_CONTROL_PARAMCHANGE = 0x6, + SERVICE_CONTROL_NETBINDADD = 0x7, + SERVICE_CONTROL_NETBINDREMOVE = 0x8, + SERVICE_CONTROL_NETBINDENABLE = 0x9, + SERVICE_CONTROL_NETBINDDISABLE = 0xA, + SERVICE_CONTROL_DEVICEEVENT = 0xB, + SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0xC, + SERVICE_CONTROL_POWEREVENT = 0xD, + SERVICE_CONTROL_SESSIONCHANGE = 0xE + } + } +} |