使用C语言关闭系统不起作用

3
我正在尝试探索使用C语言中的system()调用可以做什么。 以下是我用来关闭计算机的代码。在Windows XP上工作,但当我以Windows 7启动时,在我的机器上不起作用。可能是什么问题呢? 我已经在openSUSE 11.3 上尝试了system("shutdown -R Now"),并且也可以正常工作。这是什么原因导致了这个平台问题?我对与system()相关的例程并不太熟悉。
#include <stdio.h>
#include <stdlib.h>

int main(void)    
{    
   char ch;    

   printf("Do you want to shutdown your computer now (y/n)\n");    
   scanf("%c",&ch);    

   if (ch == 'y' || ch == 'Y')    
      system("C:\\WINDOWS\\System32\\shutdown -s");    

   return 0;
}

你是否从已提升权限的命令提示符中运行该程序? - David Schwartz
不,先生。我在win-bash上尝试过这个。 - user2045557
你是从编译器启动这个程序的吗? 你使用的是哪个编译器? - nap.gab
3
您需要在具有关闭系统权限的上下文中运行程序。对于Windows 7,这将是一个已提升的命令提示符。 - David Schwartz
2个回答

7
我正在尝试探索在C中使用system()调用可以做的事情。
实际上无需探索:您可以执行命令行中可以执行的任何操作。您传递给system的任何参数基本上都是在命令行上“键入”的。但这正是为什么您应该尽可能避免使用这个函数!它不安全,速度慢,没有可靠的处理错误的方法,而且几乎总有更好的方法来完成您想要的操作。
这种情况是一个很好的例子。使用system来调用shutdown.exe并不是以编程方式关闭Windows的正确方法。有一个API调用可供使用:ExitWindowsEx。`uFlags`参数用于指示您是否希望系统注销拥有调用该函数的进程的用户、重新启动系统或关闭系统。
您可以像这样从C中使用它:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>  // need this to call Windows APIs

int main(void)    
{    
   char ch;    

   printf("Do you want to shutdown your computer now (y/n)\n");    
   scanf("%c",&ch);    

   if (ch == 'y' || ch == 'Y')
      ExitWindowsEx(EWX_POWEROFF, 0);

   return 0;
}

当然,就像使用system调用shutdown.exe一样,应用程序需要适当的权限才能启动系统关闭。简单地说,你需要以管理员权限运行应用程序。正如David所建议的,从提升的命令提示符中运行。如果您感兴趣,ExitWindowsEx函数的链接文档有关于安全模型的更多细节。
显而易见的批评是,ExitWindowsEx是特定于平台的。在基于Unix的机器上无法调用此函数,因为它没有被实现。你将需要调用适当的POSIX API(或者你所在平台的API)。如果你真的想编写跨平台代码,那就需要使用条件编译(即#if语句)来检测目标操作系统并调用相应的API,这很丑陋。
问题在于,system函数也具有同样的限制。无论传递什么参数都会像您在命令行中键入它们一样执行。不同操作系统中的命令行环境非常不同。如果Windows和其他某些操作系统都有一个shutdown命令,那只是巧合而已。即使如此,也不太可能完全相同。因此,您仍然需要使用丑陋的平台相关代码。最好还是调用适当的系统API。 system函数的主要用途是允许您从自己的应用程序启动另一个应用程序。但是,也有一个API函数:CreateProcess。它更强大,可以接受各种参数以精确控制启动进程的行为。最重要的是,它提供了标准化的报告和处理错误的方式。
哦,对了,硬编码路径永远是错误的,无论您是使用systemCreateProcess还是一个低级批处理文件。系统驱动器可能不是“C”。Windows可能没有安装在名为“Windows”的目录中。等等。这是调用适当的操作系统API的另一个好处:它们不需要硬编码路径或特殊知识来了解默认命令提示符环境(即路径)。

在默认配置下,Windows 不需要您具有管理员特权才能关闭计算机。 - Harry Johnston
我不知道,“Windows的默认配置”这种东西是否存在。我猜我们假设的是非服务器版本?你确定受限制的用户可以关闭系统吗?在我的看法中,这是“默认配置”的一部分。 - Cody Gray
具体来说,您必须拥有“关闭系统”用户权限才能关闭系统。在客户端 SKU 中,默认情况下将此权限授予用户组(以及管理员和备份操作员)。在这种情况下,“默认情况下”意味着“除非有人更改了它”,即这是 Windows 预装的设置。 - Harry Johnston

1

适用于Windows XP

system("C:\\WINDOWS\\System32\\shutdown -s");

适用于Windows 7

system("C:\\WINDOWS\\System32\\shutdown /s");

适用于Ubuntu

system("shutdown -P now");

如果您正在使用Turbo C编译器,则需要从文件夹中执行您的文件。按F9键从源程序构建可执行文件。如果通过按ctrl+F9在编译器内运行,可能无法正常工作。

4
为什么还有人使用23年前的DOS编译器? - Lundin
2
Windows XP和7都支持在命令行中使用“/”和“-”作为开关符号。为什么您要建议使用不同的语法呢?(如果Windows没有安装在C盘上会发生什么?) - Cody Gray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接