mirror of https://github.com/dahall/Vanara.git
140 lines
8.0 KiB
C#
140 lines
8.0 KiB
C#
using System;
|
|
using Vanara.PInvoke;
|
|
using Vanara.Security.AccessControl;
|
|
using static Vanara.PInvoke.AdvApi32;
|
|
using static Vanara.PInvoke.User32;
|
|
|
|
namespace Vanara.Diagnostics
|
|
{
|
|
/// <summary>Provides access to system shutdown, restart, lock and notifications.</summary>
|
|
public static class SystemShutdown
|
|
{
|
|
/// <summary>Stops a system shutdown started by using the InitiateSystemShutdown function.</summary>
|
|
/// <param name="machineName">
|
|
/// 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.
|
|
/// </param>
|
|
/// <returns>0 on failure, non-zero for success</returns>
|
|
public static bool AbortShutdown(string machineName = null) => AbortSystemShutdown(machineName);
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="flags">Specifies the type of shutdown.</param>
|
|
/// <param name="reason">The reason for initiating the shutdown.</param>
|
|
/// <returns>
|
|
/// If the function succeeds, the return value is nonzero. <br></br><br>If the function fails, the return value is zero. To get
|
|
/// extended error information, call Marshal.GetLastWin32Error.</br>
|
|
/// </returns>
|
|
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);
|
|
}
|
|
|
|
/// <summary>Suspends the system by entering hibernation (S4).</summary>
|
|
/// <param name="wakeupEventsDisabled">
|
|
/// If this parameter is <see langword="true"/>, the system disables all wake events. If the parameter is <see langword="false"/>,
|
|
/// any system wake events remain enabled.
|
|
/// </param>
|
|
/// <returns>
|
|
/// <see langword="true"/> if the operation was successful; <see langword="false"/> if operation is not allowed by system
|
|
/// administrator settings or account privileges.
|
|
/// </returns>
|
|
public static bool Hibernate(bool wakeupEventsDisabled = false) => Suspend(true, wakeupEventsDisabled);
|
|
|
|
/// <summary>
|
|
/// Initiates a shutdown and restart of the specified computer, and restarts any applications that have been registered for restart.
|
|
/// </summary>
|
|
/// <param name="machineName">
|
|
/// The name of the computer to be shut down. If the value of this parameter is NULL, the local computer is shut down.
|
|
/// </param>
|
|
/// <param name="message">The message to be displayed in the interactive shutdown dialog box.</param>
|
|
/// <param name="gracePeriod">
|
|
/// 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.
|
|
/// <para>
|
|
/// 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.
|
|
/// </para>
|
|
/// </param>
|
|
/// <param name="flags">One or more bit flags that specify options for the shutdown.</param>
|
|
/// <param name="reason">
|
|
/// 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.
|
|
/// </param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>Initiates a shutdown and optional restart of the specified computer.</summary>
|
|
/// <param name="machineName">
|
|
/// 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.
|
|
/// </param>
|
|
/// <param name="message">
|
|
/// String that specifies a message to display in the shutdown dialog box. This parameter can be NULL if no message is required.
|
|
/// </param>
|
|
/// <param name="timeout">
|
|
/// 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.
|
|
/// </param>
|
|
/// <param name="forceAppsClosed">
|
|
/// 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.
|
|
/// </param>
|
|
/// <param name="rebootAfterShutdown">
|
|
/// 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.
|
|
/// </param>
|
|
/// <param name="reason">Reason for initiating the shutdown. This parameter must be one of the system shutdown reason codes.</param>
|
|
/// <returns>0 on failure, non-zero for success</returns>
|
|
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);
|
|
}
|
|
|
|
/// <summary>Locks the workstation's display, protecting it from unauthorized use.</summary>
|
|
public static bool LockWorkStation() => User32.LockWorkStation();
|
|
|
|
/// <summary>Suspends the system by entering a suspend (sleep) state.</summary>
|
|
/// <param name="wakeupEventsDisabled">
|
|
/// If this parameter is <see langword="true"/>, the system disables all wake events. If the parameter is <see langword="false"/>,
|
|
/// any system wake events remain enabled.
|
|
/// </param>
|
|
/// <returns>
|
|
/// <see langword="true"/> if the operation was successful; <see langword="false"/> if operation is not allowed by system
|
|
/// administrator settings or account privileges.
|
|
/// </returns>
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} |