views:

157

answers:

3

After some poking around on how to reset my computer and or shut it down from c# I found this explanation on how to do that:

        ManagementBaseObject outParameters = null;
        ManagementClass sysOS = new ManagementClass("Win32_OperatingSystem");
        sysOS.Get();
        // enables required security privilege.
        sysOS.Scope.Options.EnablePrivileges = true;
        // get our in parameters
        ManagementBaseObject inParameters = sysOS.GetMethodParameters("Win32Shutdown");
        // pass the flag of 0 = System Shutdown
        inParameters["Flags"] = "1"; //shut down.
        inParameters["Reserved"] = "0";
        foreach (ManagementObject manObj in sysOS.GetInstances())
        {
            outParameters = manObj.InvokeMethod("Win32Shutdown", inParameters, null);
        }

This worked in windows 7, but not on the windows XP box I tried it on. So I figured well lets go with a simpler solution:

Process.Start("shutdown", "/s /t 00");

Alas that as well seems to work on my windows 7 box, but not my windows XP box. I have only tried it on one windows XP machine, but it flashes up like a command prompt, my program that is up is minimized to the system tray and then nothing happens..so its like it wants to do something but ultimately nothing happens. (I do have code that purposely puts my program to the sys tray when the close X is hit, and the user has to purposely exit it... ) is there an issue with that? My FormClosing code is this:

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (!canExit)
        {
            e.Cancel = true;
            this.WindowState = FormWindowState.Minimized;
        }
        else
        {
            //write out the logs.
            List<String> logs = LogUtil.getLog();// mic.getLog();
            // create a writer and open the file
            TextWriter tw = new StreamWriter(userAppData + "\\logTMC.txt", true);

            // write a line of text to the file
            tw.WriteLine("----- " + DateTime.Now + " ------");
            foreach (String log in logs)
            {
                tw.WriteLine(log);
            }
            // close the stream
            tw.Close();
        }
    }

I am not sure why I can reset, and shutdown my pc from C# in windows 7 but not on XP...maybe I missed something? An extra command? a better way to close out the log file I have open when the form closes? some way to force a shutdown or reset no matter what, the xp box I am using does indeed have a SVN server as a windows service running, not sure if this makes a difference or not.

So not really sure where to investigate my problem, does the process.start have a way to see a return or a try catch to see what might of caused it not to shut down or is it a "fire and forget" type a deal?

+1  A: 

I can't add comments yet, so have to post it as an answer.

There is an article on this site, showing several methods on shutting down the PC here: http://stackoverflow.com/questions/102567/how-to-shutdown-the-computer-from-c

At a glance I noticed in the above link, for XP, Pop Catalin uses Process.Start("shutdown","/s /t 0");. I'm not sure if using 1 0 is going to make any difference.

François
I can try it with the one zero.
Codejoy
+1  A: 

You could use the ExitWindowsEx API via pinvoke.net.

See the ExitWindowsEx, ExitWindows-Enum and ShutdownReason-Enum on pinvoke.net for more information. Note that your process must have the SE_SHUTDOWN_NAME priviledge aquired (for example via AdjustTokenPrivileges API).

The answers to this stackoverflow question contain some "complete" examples (although most of them are missing errorchecking and resource cleanup - the latter might not matter when you successfully shutdown, YMMV).

Finally, note that using Process.Start() as you showed, without a fully qualified name to shutdown.exe is also problematic from a security standpoint. Someone could put a malicious EXE named shutdown in your PATH. Since you probably need to run with admin rights to be able to execute the "real" shutdown.exe, this can cause some trouble. If you specify something like Process.Start(Environment.ExpandEnvironmentVariables("%windir%\system32\shutdown.exe")) you can at least assume that the real shutdown.exe is protected from malicious replacement by file system rights (if the attacker himself is an admin your basically busted anyway).

Christian.K
Good point on the process start. I did try the shutdown commmand as per one of the comment suggestions on another xp box, and it did shut down just fine... not on the regular xp box. I will try the ExitWindowsEx and see if that is safer and more forceful... won't get to take a stab at it until tonight :(
Codejoy
A: 

I believe it's correct, you just have to change the command to "shutdown.exe -s -t 00". Works on my windows box (from cmd).

Phil