user2045557
user2045557

Reputation:

Shutdown the system using C does not work

I am trying to explore the things that we can do using system() call in C. Following is the code that I used to shutdown my machine. It worked on Windows XP, but does not work on my machine when I boot in Windows 7. What must be the issue? I have tried system("shutdown -R Now") on openSUSE 11.3 and it works fine there as well. What causes this platform issue in here? I am not much familiar with system() related routines.

#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;
}

Upvotes: 3

Views: 2633

Answers (2)

Cody Gray
Cody Gray

Reputation: 244843

I am trying to explore the things that we can do using system() call in C.

There is no exploring required: you can do anything that you can do from the command line. Whatever arguments you pass to system are basically "typed" at the command line. But that's precisely why you should avoid this function at all costs! It's insecure, it's slow, there's no reliable way of handling errors, and there's almost always a better way of accomplishing what you want.

This case is a good example. Using system to invoke shutdown.exe is not the right way to programmatically shut down Windows. There's an API call for that: ExitWindowsEx. The uFlags parameter is used to indicate whether you want the system to logoff the user that owns the process calling the function, restart the system, or power down the system.

You use it from C like this:

#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;
}

Of course, just like with invoking shutdown.exe using system, the application will need the appropriate permissions in order to be able to initiate a system shutdown. Simply speaking, you will need to be running the app with administrative privileges. Like David suggests, from an elevated command prompt. The linked documentation for the ExitWindowsEx function has more details on the security model if you're interested.

The obvious criticism is that ExitWindowsEx is platform-specific. You can't call this function on a Unix-based machine because it is not implemented. You'll need to call the appropriate POSIX API (or whatever it is on your platform). If you truly want to write platform-independent code, that requires you to use conditional compilation (i.e. #if statements) that detect the target OS and invoke the appropriate APIs, which is ugly.

The problem is, the system function has exactly that same limitation. Whatever arguments you pass are executed as if you'd typed them into the command line. And the command line environment in different operating systems is very different. It's simply a coincidence if both Windows and some other operating systems have a shutdown command. And even then, it's not likely to work identically. So you're still left with ugly platform-dependent code. You might as well call the right system APIs.

The main use of the system function is that it allows you to launch another application from your own application. But there is an API function for that, too: CreateProcess. It's much more powerful, accepting various arguments to control exactly how the launched process should behave. And most importantly, it provides a standardized way of reporting and handling errors.

Oh, and, hard-coding paths is always wrong, whether you're using system, CreateProcess, or a lowly batch file. The system drive might not be "C". Windows might not be installed in a directory named "Windows". And on and on. This is another benefit of calling the appropriate OS APIs: they don't require hard-coding paths or special knowledge of the default command prompt environment (i.e. the path).

Upvotes: 7

user2549006
user2549006

Reputation: 21

for Windows XP Use

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

for Windows 7

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

for Ubuntu

system("shutdown -P now");

If you are using Turbo C Compiler then execute your file from folder. Press F9 to build your executable file from source program. When you run from within the compiler by pressing ctrl+F9 it may not work.

Upvotes: 1

Related Questions