Reboot machine from a C#/WPF app
Asked Answered
N

4

42

I want to have a button in my WPF app that restarts the machine. This app is always running on Vista.

The fact that a quick search hasn't turned anything up makes me think this might be harder than I wish it was... any ideas? Thanks!

Nigritude answered 31/7, 2009 at 22:15 Comment(0)
M
81

Try this:

System.Diagnostics.Process.Start("shutdown.exe", "-r -t 0");

This starts Windows' inbuilt shutdown tool, which can also shut down or logoff a remote or the local machine.

Here is the list of full options from ss64.com:

Syntax

      SHUTDOWN [logoff_option]  [/m \\Computer] [options]

logoff_option:
    /i         Display the GUI (must be the first option)
    /l         Log off. This cannot be used with /m or /d option
    /s         Shutdown
    /r         Shutdown and Restart
    /a         Abort a system shutdown.
               (only during the time-out period)
    /p         Turn off the local computer with no time-out or warning
               (only with /d)
    /h         Hibernate the local computer (only with /f )
    /e         Document the reason for an unexpected shutdown of a computer

Options:

   /m \\Computer  : A remote computer to shutdown.

   /t:xxx         : Time until system shutdown in seconds. 
                    The valid range is xxx=0-600 seconds. [default=30]
   /c "Msg"       : An optional shutdown message [Max 127 chars]

   /f             : Force running applications to close.
                    This will not prompt for File-Save in any open applications.
                    so will result in a loss of all unsaved data!!!

   /d u:xx:yy     : List a USER reason code for the shutdown. 
   /d P:xx:yy     : List a PLANNED reason code for the shutdown.
                     xx Specifies the major reason code (0-255)
                     yy Specifies the minor reason code (0-65536)

You'll probably notice that I have used the Linux/UNIX style of passing command-line arguments (using the '-') sign. On Windows, the convention is using '/'. This doesn't matter - the program doesn't care.

Martsen answered 31/7, 2009 at 22:16 Comment(1)
this is more useful for both windows and linuxPentagon
T
23

You can use the ExitWindowsEx API. From pinvoke.net

[Flags]
public enum ExitWindows : uint
{
   // ONE of the following five:
   LogOff = 0x00,
   ShutDown = 0x01,
   Reboot = 0x02,
   PowerOff = 0x08,
   RestartApps = 0x40,
   // plus AT MOST ONE of the following two:
   Force = 0x04,
   ForceIfHung = 0x10,
}

[Flags]
enum ShutdownReason : uint
{
    MajorApplication = 0x00040000,
    MajorHardware = 0x00010000,
    MajorLegacyApi = 0x00070000,
    MajorOperatingSystem = 0x00020000,
    MajorOther = 0x00000000,
    MajorPower = 0x00060000,
    MajorSoftware = 0x00030000,
    MajorSystem = 0x00050000,

    MinorBlueScreen = 0x0000000F,
    MinorCordUnplugged = 0x0000000b,
    MinorDisk = 0x00000007,
    MinorEnvironment = 0x0000000c,
    MinorHardwareDriver = 0x0000000d,
    MinorHotfix = 0x00000011,
    MinorHung = 0x00000005,
    MinorInstallation = 0x00000002,
    MinorMaintenance = 0x00000001,
    MinorMMC = 0x00000019,
    MinorNetworkConnectivity = 0x00000014,
    MinorNetworkCard = 0x00000009,
    MinorOther = 0x00000000,
    MinorOtherDriver = 0x0000000e,
    MinorPowerSupply = 0x0000000a,
    MinorProcessor = 0x00000008,
    MinorReconfig = 0x00000004,
    MinorSecurity = 0x00000013,
    MinorSecurityFix = 0x00000012,
    MinorSecurityFixUninstall = 0x00000018,
    MinorServicePack = 0x00000010,
    MinorServicePackUninstall = 0x00000016,
    MinorTermSrv = 0x00000020,
    MinorUnstable = 0x00000006,
    MinorUpgrade = 0x00000003,
    MinorWMI = 0x00000015,

    FlagUserDefined = 0x40000000,
    FlagPlanned = 0x80000000
}

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ExitWindowsEx(ExitWindows uFlags, ShutdownReason dwReason);

And to use it:

ExitWindowsEx(
  ExitWindows.Reboot,
  ShutdownReason.MajorOther | ShutdownReason.MinorOther | ShutdownReason.FlagPlanned
); 
Tigre answered 31/7, 2009 at 22:40 Comment(6)
This won't work unless you also adjust the process token to get shutdown privileges. See ithoughthecamewithyou.com/post/Reboot-computer-in-C-NET.aspx for a class that does this properly.Henry
It works for me without setting any process token. WPF app with UAC enabled, Win7 x64.Spiro
You want to pass the second parameter to ExitWindowsEx like this: ShutdownReason.MajorOther | ShutdownReason.MinorOther | ShutdownReason.FlagPlanned. Using the bitwise AND will just zero the argument out. The system will be left with the report of an unplanned and unspecified shutdown in the Shutdown Event Tracker. Read more here: msdn.microsoft.com/en-us/library/windows/desktop/…Yearlong
@DerekW: Thanks for pointing out the typo and suggesting FlagPlanned. I have edited the answer to incorporate your suggestions.Tigre
@RobertEllison It does work as Administrator on Windows 7, but no longer on Windows 10 which I have now seen. Error 1314.Efficiency
@Efficiency > did you try with Robert Elison's solution ?Stellular
T
10

An alternative would be to use WMI (i.e. the System.Management namespace); Google brings up variations on this code --

  ManagementClass W32_OS = new ManagementClass("Win32_OperatingSystem")
  ManagementBaseObject inParams, outParams;
  int result;
  W32_OS.Scope.Options.EnablePrivileges = true;

  foreach(ManagementObject obj in W32_OS.GetInstances())
  {
    inParams = obj.GetMethodParameters("Win32Shutdown");
    inParams["Flags"] = 6; //ForcedReboot; -- fixed to restart rather than shutdown
    inParams["Reserved"] = 0;

    outParams = obj.InvokeMethod("Win32Shutdown", inParams, null)
    result = Convert.ToInt32(outParams["returnValue"]);
    if (result !=0) throw new Win32Exception(result);
  }
Tabloid answered 31/7, 2009 at 22:33 Comment(0)
C
1

Working code inside a windows service:

var cmd = new System.Diagnostics.ProcessStartInfo("shutdown.exe", "-r -t 0");
cmd.CreateNoWindow = true;
cmd.UseShellExecute = false;
cmd.ErrorDialog = false;
System.Diagnostics.Process.Start(cmd);
Claribel answered 25/6, 2020 at 5:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.