6

Is it possible, without employing pinvoke, to restart a PC using .NET?

I kind of just repeated the title, but I'm not too sure how to elaborate much further!

Edit:

I should have mentioned that don't want to use "shutdown -r" as a solution.

I was really after a pure .NET way, something like:

Environment.ShutDown();

In other words, something that is maintained with .NET as new versions of Windows arise.

Edit 2:

Please stop asking "what's wrong with p/invoke". Those sort of answers are exactly what SO users seem to love; the supposed "lateral" approach to answering a question. However, although there is no real problem with p/invoke and I will happily use it, what on earth is wrong with asking if .NET has a more official way of achieving something? If it's in .NET then any API changes between OSes will (most likely) get reflected. Whatever the reason, it's not a crime to seek to minimise DLL import usage is it?

I'm sure if I included something in a question like:

[DllImport("something32.dll")]
static extern int ClimbWall32Ex(IntPtr32 blah);

And you could just do:

SomeNamespace.ClimbWall();

Everyone one here would scream: "what is wrong with using SomeNamespace.ClimbWall();??"

Sigh.

joshcomley
  • 28,099
  • 24
  • 107
  • 147
  • 9
    What is the problem with using P/Invoke? It's there to be used and it is widely used within the BCL. – Dirk Vollmar Oct 14 '09 at 13:07
  • 2
    ...and even if there was an object exposing a method for rebooting I'd bet it would just be calling the native Windows API functions under the hood. – Dirk Vollmar Oct 14 '09 at 13:10
  • There isn't a problem with using p/invoke, and most of .NET is just a wrapper for Windows API, but if there was a .NET way of doing things then generally speaking you should use it! For example, any updates in new OSes etc. that might not support old API calls will be fixed (!) with an update to .NET – joshcomley Oct 14 '09 at 13:22
  • That's the problem with saying "pure" .NET - what do you think the .NET APIs really do? Anything that interacts with the system must call Windows APIs at some level. – We Are All Monica Oct 14 '09 at 13:41
  • 1
    @jnylen - You're missing the point! If I was using "pure" .NET as I put it then I would be transferring responsibility of maintenance of that method to the .NET framework as opposed to me. Suppose in Windows "8" that API method is no longer supported? If I used Environment.ShutDown() I'm sure that .NET 5 (or whatever) would be updated to reflect that. I am fully aware of what .NET is and how it works! Obviously, I can't *rely* on .NET being updated, but it sure helps to give it a chance. – joshcomley Oct 14 '09 at 14:27
  • @joshcomley: I understand your concern, but backward compatibility has always been a very important issue in each new Windows version. As long as you rely on documented functionality you are pretty safe in my opinion. – Dirk Vollmar Oct 14 '09 at 14:37
  • @divo - yep I'm absolutely sure I would be, but I still don't see the problem with asking! – joshcomley Oct 14 '09 at 14:43
  • There is no problem with asking, I was just curious, whether there would be any particular problem with using the native API. And I think you have given an answer to that. This was not to critize you. However, I have seen it more than once that users are asking for a specific solution whereas their problem might be solvable in a much simpler fashion using a different approach. Therefore my question. – Dirk Vollmar Oct 14 '09 at 15:40

3 Answers3

15

Not sure why you wouldn't just use P/Invoke, but one alternate way of restarting would be to use System.Diagnostics.Process.Start in conjunction with the shutdown command.

Example:

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


If that also isn't acceptable, you could look into using WMI (see here for an example that could probably be modified to suit your purposes).

Donut
  • 110,061
  • 20
  • 134
  • 146
  • I had considered this, but it is running from a windows service so this won't work..(?) – joshcomley Oct 14 '09 at 13:05
  • You could also add the -f (force) switch. One downside to this; it will inform the user that the machine is about to restart, however I don't think you can cancel it... – ParmesanCodice Oct 14 '09 at 13:06
  • 3
    It will work just fine. I'm using "shutdown -r -t 01" to restart my server (from a nncron running as a service) – Davorin Oct 14 '09 at 13:08
  • @Davorin - ah right, I wasn't sure (hence the question mark at the end of my statement!) – joshcomley Oct 14 '09 at 13:40
10

You can use WMI to restart. Below is from memory, but I think it is pretty close, although a little sloppy. :)

var computer = "COMPUTERNAME";
var query = string.Format("SELECT * FROM Win32_OperatingSystem");

ManagementScope scope;

var computerPath = string.Format(@"\\{0}\root\cimv2", computer);

scope = new ManagementScope(computerPath);

scope.Connect();

var q = new ObjectQuery(query);
var s = new ManagementObjectSearcher(scope, q);

ManagementObjectCollection qr;

qr = s.Get();

foreach (ManagementObject r in qr) 
{
    string[] p = { "" };
    r.InvokeMethod("Reboot", p);
}
TWA
  • 12,756
  • 13
  • 56
  • 92
7

You need to call ExitWindowsEx which is only available through DllImport

rslite
  • 81,705
  • 4
  • 44
  • 47