Win32APIs 关机程序 (C)

来源:互联网 发布:win10有线网络连接不上 编辑:程序博客网 时间:2024/04/30 20:29

//可以看到C写Win32 APIs Console 程序很方便

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#pragma hdrstop

BOOL SetCurrentPrivilege( LPCTSTR Privilege, BOOL bEnablePrivilege );
void DisplayError( DWORD err );

int main( int argc, char * argv[] )
{
 int i, errors = 0, local = 0, timeout = -1, force = 0, reboot = 0, oops = 0;
 char *remote = NULL, *message = NULL;
 BOOL rc;

 if ( argc == 1 )
 {
usage:
  if ( errors )
   putchar( '/n' );
  puts( "reboot {-l | -s servername} [-m /"message/"] [-t timeout] [-f] [-r] [-oops]/n" );
  puts( "-l             reboot local machine" );
  puts( "-s servername  reboot named computer" );
  puts( "-t timeout     show a logoff dialog for <timeout> seconds; 0 suppresses it" );
  puts( "-m /"message/"   display /"message/" in that dialog" );
  puts( "-f             force apps closed" );
  puts( "-r             reboot after shutdown" );
  puts( "-oops          aborts a previous shutdown request (only -l, -s count)" );
  return 1;
 }

 for ( i = 1; i < argc; i ++ )
 {
  if ( *argv[i] != '-' && *argv[i] != '/' )
  {
   printf( "/"%s/": switches must start with a '-' or '/' character./n", argv[i] );
   errors ++;
   continue;
  }

  ++ argv[i];
  switch ( *argv[i] )
  {
   case 'l':
    if ( remote != NULL || local != 0 )
    {
     puts( "Only one of -l and -s may be used." );
     ++ errors;
    }
    else
     ++ local;
    break;
   case 's':
    if ( remote != NULL || local != 0 )
    {
     puts( "Only one of -l and -s may be used." );
     ++ errors;
    }
    else if ( i == argc - 1 )
    {
     puts( "-s must be followed by the name of the server to shut down." );
     ++ errors;
    }
    else
    {
     ++ i;
     remote = argv[i];
    }
    break;
   case 't':
    if ( timeout != -1 )
    {
     puts( "Only one timeout may be used." );
     ++ errors;
    }
    else if ( i == argc - 1 )
    {
     puts( "-t must be followed by a timeout." );
     ++ errors;
    }
    else
    {
     ++ i;
     timeout = atoi( argv[i] );
    }
    break;
   case 'm':
    if ( message != NULL )
    {
     puts( "Only one message may be used." );
     ++ errors;
    }
    else if ( i == argc - 1 )
    {
     puts( "-m must be followed by the message text." );
     ++ errors;
    }
    else
    {
     ++ i;
     message = argv[i];
    }
    break;
   case 'f':
    if ( force )
    {
     puts( "-f may only be used once." );
     ++ errors;
    }
    else
     ++ force;
    break;
   case 'r':
    if ( reboot )
    {
     puts( "-r may only be used once." );
     ++ errors;
    }
    else
     ++ reboot;
    break;
   case 'o':
    ++ oops;
    break;
   default:
    printf( "/"%s/" is not a valid switch./n", argv[i] - 1 );
    ++ errors;
    break;
  }
 }

 if ( local == 0 && remote == NULL )
 {
  puts( "One of -l and -s must be used." );
  ++ errors;
 }

 if ( ! oops && timeout == -1 ) // no timeout used
 {
  puts( "Anti-goof feature: you must specify a timeout (0 seconds is OK)" );
  ++ errors;
 }

 if ( errors )
  goto usage;

 if ( local )
 {
  if ( ! SetCurrentPrivilege( SE_SHUTDOWN_NAME, TRUE ) )
  {
   DisplayError( GetLastError() );
   return 2;
  }
 }

 if ( oops )
 {
  printf( "/nTrying to abort the shutdown of %s ...", remote? remote: "this computer" );
  rc = AbortSystemShutdown( remote );
 }
 else
 {
  printf( "/nTrying to shut down %s in %d seconds ...", remote? remote: "this computer", timeout );
  rc = InitiateSystemShutdown( remote, message, (DWORD) timeout, force, reboot );
 }

 putchar( '/n' );

 if ( ! rc )
 {
  DisplayError( GetLastError() );
  return 1;
 }

 return 0;
}

 

BOOL SetCurrentPrivilege( LPCTSTR Privilege, BOOL bEnablePrivilege )
{
 HANDLE hToken;
 LUID luid;
 TOKEN_PRIVILEGES tp, tpPrevious;
 DWORD cbPrevious = sizeof( TOKEN_PRIVILEGES );
 BOOL bSuccess = FALSE;

 if ( ! LookupPrivilegeValue( NULL, Privilege, &luid ) )
  return FALSE;

 if( ! OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken ) )
  return FALSE;

 tp.PrivilegeCount = 1;
 tp.Privileges[0].Luid = luid;
 tp.Privileges[0].Attributes = 0;

 AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof( TOKEN_PRIVILEGES ), &tpPrevious, &cbPrevious );

 if ( GetLastError() == ERROR_SUCCESS )
 {
  tpPrevious.PrivilegeCount = 1;
  tpPrevious.Privileges[0].Luid = luid;

  if ( bEnablePrivilege )
   tpPrevious.Privileges[0].Attributes |= ( SE_PRIVILEGE_ENABLED );
  else
   tpPrevious.Privileges[0].Attributes &= ~( SE_PRIVILEGE_ENABLED );

  AdjustTokenPrivileges( hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL );

  if ( GetLastError() == ERROR_SUCCESS )
   bSuccess=TRUE;
 }

 CloseHandle( hToken );

 return bSuccess;
}

void DisplayError( DWORD err )
{
 char msgbuf[4096];

 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT),
  msgbuf, sizeof( msgbuf ), NULL );
 printf( "Error %d: %s/n", err, msgbuf );
}

 

原创粉丝点击