3

C で callを使用してできることを調べようとしていsystem()ます。以下は、マシンをシャットダウンするために使用したコードです。Windows XP では動作しましたが、Windows 7 で起動すると自分のマシンでは動作しません。何が問題なのですか? system("shutdown -R Now")openSUSE 11.3 で試してみましたが、そこでも問題なく動作します。このプラットフォームの問題の原因は何ですか? 私は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;
}
4

2 に答える 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;
}

もちろん、 を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 つの利点です。パスをハードコーディングしたり、デフォルトのコマンド プロンプト環境 (つまり、パス) に関する特別な知識を必要としません。

于 2013-07-05T07:51:09.103 に答える
1

Windows XP 用

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

Windows 7 の場合

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

Ubuntu の場合

system("shutdown -P now");

Turbo C Compiler を使用している場合は、フォルダーからファイルを実行します。F9 キーを押して、ソース プログラムから実行可能ファイルをビルドします。ctrl+F9 を押してコンパイラ内から実行すると、動作しない場合があります。

于 2013-07-05T07:37:06.200 に答える