【问题标题】:Shutdown the system using C does not work使用 C 关闭系统不起作用
【发布时间】:2013-07-05 07:28:19
【问题描述】:

我正在尝试探索在 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;
}

【问题讨论】:

  • 您是否从提升的命令提示符运行程序?
  • 不,先生。我在 win-bash 上试过这个
  • 你是从你的编译器启动这个程序吗?你用的是什么编译器?
  • 您需要从有权关闭系统的上下文中运行程序。对于 Windows 7,这将是一个提升的命令提示符。

标签: c windows shutdown


【解决方案1】:

我正在尝试探索在 C 中使用 system() 调用我们可以做的事情。

无需探索:您可以从命令行执行任何可以执行的操作。无论您传递给system 的任何参数基本上都是在命令行中“键入”的。但这正是您应该不惜一切代价避免使用此功能的原因!它不安全,速度慢,没有可靠的方法来处理错误,而且几乎总是有更好的方法来完成你想要的。

这个案例就是一个很好的例子。使用system 调用shutdown.exe 不是以编程方式关闭Windows 的正确方法。有一个 API 调用:ExitWindowsExuFlags参数用于表示是否希望系统注销拥有调用该函数的进程的用户、重新启动系统或关闭系统。

你可以像这样从 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 一样,应用程序需要适当的权限才能启动系统关闭。简而言之,您需要以管理权限运行该应用程序。 Like David suggests,来自提升的命令提示符。如果您有兴趣,ExitWindowsEx 函数的链接文档会提供有关安全模型的更多详细信息。

明显的批评是ExitWindowsEx 是特定于平台的。你不能在基于 Unix 的机器上调用这个函数,因为它没有被实现。您需要调用适当的 POSIX API(或您平台上的任何 API)。如果你真的想编写独立于平台的代码,那需要你使用条件编译(即#if 语句)来检测目标操作系统并调用相应的API,这很难看。

问题是,system 函数具有完全相同的限制。无论您传递什么参数,都会像在命令行中输入它们一样执行。并且不同操作系统下的命令行环境有很大的不同。如果 Windows 和其他一些操作系统都有 shutdown 命令,这只是一个巧合。即便如此,它也不太可能以同样的方式工作。所以你仍然留下丑陋的平台相关代码。您不妨调用系统API。

system 函数的主要用途是它允许您从自己的应用程序启动另一个应用程序。但也有一个 API 函数:CreateProcess。它更强大,可以接受各种参数来准确控制启动进程的行为方式。最重要的是,它提供了一种报告和处理错误的标准化方式。

哦,而且,硬编码路径总是错误的,无论您使用的是 systemCreateProcess 还是低级批处理文件。系统驱动器可能不是“C”。 Windows 可能未安装在名为“Windows”的目录中。不断地。这是调用适当的 OS API 的另一个好处:它们不需要硬编码路径或默认命令提示符环境(即路径)的特殊知识。

【讨论】:

  • 在默认配置中,Windows 不要求您具有管理员权限来关闭机器。
  • 我不知道,我认为没有“Windows 的默认配置”之类的东西。我想我们假设非服务器 SKU?您确定受限用户可以关闭系统吗?从我的角度来看,这是“默认配置”的一部分。
  • 具体来说,您必须拥有“关闭系统”用户权限才能关闭系统。在客户端 SKU 中,这默认授予用户组(以及管理员和备份操作员)。 (“默认情况下”在这种情况下表示“除非有人更改它”,即这是 Windows 附带的设置。)
【解决方案2】:

适用于 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 运行时,它可能不起作用。

【讨论】:

  • 为什么有人还在使用 23 岁的 DOS 编译器?
  • Windows XP 和 7 都支持 /- 用于命令行开关。你为什么建议使用不同的语法? (如果 C 盘上没有安装 Windows 会怎样?)
猜你喜欢
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-15
  • 2013-06-20
  • 1970-01-01
相关资源
最近更新 更多