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
使用して呼び出す場合と同様system
に、システムのシャットダウンを開始するには、アプリケーションに適切な権限が必要です。簡単に言えば、管理者権限でアプリを実行する必要があります。David が示唆するように、昇格したコマンド プロンプトから。興味がある場合は、関数のリンクされたドキュメントにExitWindowsEx
セキュリティ モデルの詳細が記載されています。
明らかな批判は、それExitWindowsEx
がプラットフォーム固有であるということです。この関数は実装されていないため、Unix ベースのマシンでは呼び出すことができません。適切な POSIX API (またはプラットフォームにあるもの) を呼び出す必要があります。プラットフォームに依存しないコードを本当に書きたい場合は#if
、ターゲット OS を検出して適切な API を呼び出す条件付きコンパイル (ステートメントなど) を使用する必要がありますが、これは見苦しいものです。
問題は、system
関数にまったく同じ制限があることです。渡した引数は、コマンド ラインに入力したかのように実行されます。また、オペレーティング システムが異なれば、コマンド ライン環境も大きく異なります。Windows とその他のオペレーティング システムの両方にshutdown
コマンドがある場合は、単なる偶然です。それでも、同じように機能する可能性は低いです。そのため、プラットフォームに依存する醜いコードが残っています。適切なシステム APIを呼び出すこともできます。
この機能の主な用途は、system
自分のアプリケーションから別のアプリケーションを起動できるようにすることです。しかし、そのための API 関数もあります: CreateProcess
. 起動されたプロセスがどのように動作するかを正確に制御するためのさまざまな引数を受け入れる、はるかに強力です。そして最も重要なことは、エラーの報告と処理の標準化された方法を提供することです。
ああ、ハード コーディング パスは常に間違っていsystem
ますCreateProcess
。システムドライブが「C」でない可能性があります。「Windows」という名前のディレクトリに Windows がインストールされていない可能性があります。そしてどんどん。これは、適切な OS API を呼び出すもう 1 つの利点です。パスをハードコーディングしたり、デフォルトのコマンド プロンプト環境 (つまり、パス) に関する特別な知識を必要としません。