Win32APIs 关机程序 (C)

转载 2006年06月18日 08:57:00

//可以看到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 );
}

 

用Win32写的定时关机程序

由于本人记性不太好,晚上经常忘记关电脑,白白浪费了很多的电。在网上也找了一些定时关机的软件,想到最近自己也在学习VC++,就想自己写一个定时关机的小程序,正好也可以检验自己所学的东西。 先来看看效果图...
  • qutadi
  • qutadi
  • 2014年07月28日 15:57
  • 706

用Win32写的定时关机程序

由于本人记性不太好,晚上经常忘记关电脑,白白浪费了很多的电。在网上也找了一些定时关机的软件,想到最近自己也在学习VC++,就想自己写一个定时关机的小程序,正好也可以检验自己所学的东西。 程序源码下载...
  • qutadi
  • qutadi
  • 2014年07月28日 16:19
  • 556

Visual Studio 2015专业版创建Win32控制台应用程序,C,C++源文件

问题: 原配的Visual Studio 2015专业版不像之前的版本,在新建项目里面是找不到Win32模板的,那么怎么才能新建Win32项目和Win32控制台应用程序呢?先看如下图所示: ...
  • dddxxxx
  • dddxxxx
  • 2017年05月17日 15:44
  • 939

用C写一个简单的win32服务程序

windows服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务。         服务时一个运行在后台并实现无需用户交互的任务的控制台程序。 本文只是简单的实现定期向文本文件写入内...
  • aa1991
  • aa1991
  • 2013年04月17日 13:42
  • 473

第一次写WIN32 SOCKET C/S模式聊天程序有感

第一次写WIN32 SOCKET C/S模式聊天程序有感

Visual Studio 2015专业版创建Win32控制台应用程序,C,C++源文件

问题: 原配的Visual Studio 2005专业版不像之前的版本,在新建项目里面是找不到Win32模板的,那么怎么才能新建Win32项目和Win32控制台应用程序呢?先看如下图所示: 解决:...

将 Win32 C/C++ 应用程序迁移到 POWER 上的 Linux,第 1 部分: 进程、线程和共享内存服务

概述 有很多方式可以将 Win32 C/C++ 应用程序移植和迁移到 pSeries 平台。您可以使用免费软件或者第三方工具来将 Win32 应用程序代码移到 Linux。在我们的方案中,我们决...

将 Win32 C/C++ 应用程序迁移到 POWER 上的 Linux,第 1 部分: 进程、线程和共享内存服务

特别是进程、线程和共享内存服务)到 POWER 上 Linux 的映射。本文可以帮助您确定哪种映射服务最适合您的需要。作者向您详细介绍了他在移植 Win32 C/C++ 应用程序时遇到的 API 映射...
  • educast
  • educast
  • 2013年08月17日 09:26
  • 843

C# Win32控制台应用程序忽略 Ctrl + C,阻止程序退出

C# Win32控制台应用程序忽略 Ctrl + C,阻止程序退出,这里使用到了Windows API SetConsoleCtrlHandler函数注意:在VS中调试执行时,在处理程序例程中设置断点...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Win32APIs 关机程序 (C)
举报原因:
原因补充:

(最多只允许输入30个字)