我正在尝试探索我们可以使用 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;
}
当然,就像调用shutdown.exe
using一样system
,应用程序需要适当的权限才能启动系统关闭。简而言之,您需要以管理权限运行该应用程序。就像大卫建议的那样,来自提升的命令提示符。ExitWindowsEx
如果您有兴趣,该函数的链接文档会提供有关安全模型的更多详细信息。
明显的批评是ExitWindowsEx
特定于平台的。你不能在基于 Unix 的机器上调用这个函数,因为它没有被实现。您需要调用适当的 POSIX API(或您平台上的任何 API)。如果你真的想编写独立于平台的代码,那需要你使用条件编译(即#if
语句)来检测目标操作系统并调用适当的 API,这很难看。
问题是,该system
功能具有完全相同的限制。无论您传递什么参数,都会像在命令行中输入它们一样执行。并且不同操作系统下的命令行环境有很大的不同。如果 Windows 和其他一些操作系统都有shutdown
命令,那只是巧合。即便如此,它也不太可能以同样的方式工作。所以你仍然留下丑陋的平台相关代码。您不妨调用正确的系统 API。
该system
功能的主要用途是它允许您从自己的应用程序启动另一个应用程序。但也有一个 API 函数:CreateProcess
. 它更强大,可以接受各种参数来准确控制启动进程的行为方式。最重要的是,它提供了一种报告和处理错误的标准化方式。
哦,而且,硬编码路径总是错误的,无论您使用的是system
,CreateProcess
还是低级批处理文件。系统驱动器可能不是“C”。Windows 可能未安装在名为“Windows”的目录中。不断地。这是调用适当的操作系统 API 的另一个好处:它们不需要硬编码路径或默认命令提示符环境(即路径)的特殊知识。