using System; using Vanara.PInvoke; using Vanara.Security.AccessControl; using static Vanara.PInvoke.AdvApi32; using static Vanara.PInvoke.User32; namespace Vanara.Diagnostics { /// Provides access to system shutdown, restart, lock and notifications. public static class SystemShutdown { /// Stops a system shutdown started by using the InitiateSystemShutdown function. /// /// String that specifies the network name of the computer where the shutdown is to be stopped. If NULL or an empty string, the /// function stops the shutdown on the local computer. /// /// 0 on failure, non-zero for success public static bool AbortShutdown(string machineName = null) => AbortSystemShutdown(machineName); /// /// Logs off the current user, shuts down the system, or shuts down and restarts the system. It sends the WM_QUERYENDSESSION message /// to all applications to determine if they can be terminated. /// /// Specifies the type of shutdown. /// The reason for initiating the shutdown. /// /// If the function succeeds, the return value is nonzero.


If the function fails, the return value is zero. To get /// extended error information, call Marshal.GetLastWin32Error.
///
public static bool ExitWindows(ExitWindowsFlags flags = ExitWindowsFlags.EWX_LOGOFF, SystemShutDownReason reason = SystemShutDownReason.SHTDN_REASON_UNKNOWN) { var reqPriv = (flags & (ExitWindowsFlags.EWX_POWEROFF | ExitWindowsFlags.EWX_REBOOT | ExitWindowsFlags.EWX_SHUTDOWN)) != 0; using (new PrivilegedCodeBlock(reqPriv ? new[] { SystemPrivilege.Shutdown } : new SystemPrivilege[0])) return ExitWindowsEx(flags, reason); } /// Suspends the system by entering hibernation (S4). /// /// If this parameter is , the system disables all wake events. If the parameter is , /// any system wake events remain enabled. /// /// /// if the operation was successful; if operation is not allowed by system /// administrator settings or account privileges. /// public static bool Hibernate(bool wakeupEventsDisabled = false) => Suspend(true, wakeupEventsDisabled); /// /// Initiates a shutdown and restart of the specified computer, and restarts any applications that have been registered for restart. /// /// /// The name of the computer to be shut down. If the value of this parameter is NULL, the local computer is shut down. /// /// The message to be displayed in the interactive shutdown dialog box. /// /// The number of seconds to wait before shutting down the computer. If the value of this parameter is zero, the computer is shut /// down immediately. This value is limited to MAX_SHUTDOWN_TIMEOUT. /// /// If the value of this parameter is greater than zero, and the dwShutdownFlags parameter specifies the flag /// SHUTDOWN_GRACE_OVERRIDE, the function fails and returns the error code ERROR_BAD_ARGUMENTS. /// /// /// One or more bit flags that specify options for the shutdown. /// /// The reason for initiating the shutdown. This parameter must be one of the system shutdown reason codes. If this parameter is /// zero, the default is an undefined shutdown that is logged as "No title for this reason could be found". By default, it is also an /// unplanned shutdown. Depending on how the system is configured, an unplanned shutdown triggers the creation of a file that /// contains the system state information, which can delay shutdown. Therefore, do not use zero for this parameter. /// public static void InitiateShutdown(string machineName, string message, TimeSpan gracePeriod, ShutdownFlags flags, SystemShutDownReason reason = SystemShutDownReason.SHTDN_REASON_UNKNOWN) { var graceSecs = (uint)gracePeriod.TotalSeconds; if (graceSecs > MAX_SHUTDOWN_TIMEOUT) throw new ArgumentOutOfRangeException(nameof(gracePeriod), $"Grace period can be no longer than {MAX_SHUTDOWN_TIMEOUT} seconds."); using (string.IsNullOrEmpty(machineName) ? new PrivilegedCodeBlock(SystemPrivilege.Shutdown) : new PrivilegedCodeBlock(SystemPrivilege.RemoteShutdown)) AdvApi32.InitiateShutdown(machineName, message, graceSecs, flags, reason); } /// Initiates a shutdown and optional restart of the specified computer. /// /// String that specifies the network name of the computer to shut down. If NULL or an empty string, the function shuts down the /// local computer. /// /// /// String that specifies a message to display in the shutdown dialog box. This parameter can be NULL if no message is required. /// /// /// Time that the shutdown dialog box should be displayed, in seconds. While this dialog box is displayed, shutdown can be stopped by /// the AbortSystemShutdown function. /// /// /// If this parameter is TRUE, applications with unsaved changes are to be forcibly closed. If this parameter is FALSE, the system /// displays a dialog box instructing the user to close the applications. /// /// /// If this parameter is TRUE, the computer is to restart immediately after shutting down. If this parameter is FALSE, the system /// flushes all caches to disk and clears the screen. /// /// Reason for initiating the shutdown. This parameter must be one of the system shutdown reason codes. /// 0 on failure, non-zero for success public static bool InitiateShutdown(string machineName = null, string message = null, TimeSpan? timeout = null, bool forceAppsClosed = false, bool rebootAfterShutdown = false, SystemShutDownReason reason = SystemShutDownReason.SHTDN_REASON_UNKNOWN) { var graceSecs = (uint)timeout.GetValueOrDefault().TotalSeconds; if (Environment.OSVersion.Version.Major <= 5 && graceSecs > MAX_SHUTDOWN_TIMEOUT) throw new ArgumentOutOfRangeException(nameof(timeout), $"Timeout can be no longer than {MAX_SHUTDOWN_TIMEOUT} seconds on Windows XP and earlier systems."); using (string.IsNullOrEmpty(machineName) ? new PrivilegedCodeBlock(SystemPrivilege.Shutdown) : new PrivilegedCodeBlock(SystemPrivilege.RemoteShutdown)) return InitiateSystemShutdownEx(machineName, message, graceSecs, forceAppsClosed, rebootAfterShutdown, reason); } /// Locks the workstation's display, protecting it from unauthorized use. public static bool LockWorkStation() => User32.LockWorkStation(); /// Suspends the system by entering a suspend (sleep) state. /// /// If this parameter is , the system disables all wake events. If the parameter is , /// any system wake events remain enabled. /// /// /// if the operation was successful; if operation is not allowed by system /// administrator settings or account privileges. /// public static bool Suspend(bool wakeupEventsDisabled = false) => Suspend(false, wakeupEventsDisabled); private static bool Suspend(bool hibernate, bool wakeupEventsDisabled) { try { using (new PrivilegedCodeBlock(SystemPrivilege.Shutdown)) { if (hibernate) return PowrProf.IsPwrHibernateAllowed() ? PowrProf.SetSuspendState(true, false, wakeupEventsDisabled) : false; else return PowrProf.IsPwrSuspendAllowed() ? PowrProf.SetSuspendState(false, false, wakeupEventsDisabled) : false; } } catch { return false; } } } }