How to shut down from C#, Process.Start(“shutdown”) not working in Windows XP

六眼飞鱼酱① 提交于 2019-12-10 19:23:27

问题


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 Windows 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 Windows XP box I am using does indeed have an SVN server as a windows service running, but I am not sure if this makes a difference or not.

So I am 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:


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).




回答2:


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: How to shut down 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.




回答3:


I believe it's correct. You just have to change the command to:

shutdown.exe -s -t 00

It works on my Windows box (from cmd).



来源:https://stackoverflow.com/questions/3724276/how-to-shut-down-from-c-process-startshutdown-not-working-in-windows-xp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!