强制电脑定时休息的服务程序

     自从儿子上周从上海回来后,天天泡在电脑上。我很担心他的视力,不过秋老虎这么厉害,除了晚上能够带他到操场活动外,白天也只能闷在空调屋里活动啦,不让他玩也过于不近人情。“堵不如疏”,就打算给他装个定时开关机软件,免得我不在家的时候他不知节制地消耗视力。儿子有一定的电脑软件安装基础,网上所找到的定时开关机软件都不符合要求。于是,就自己写了一个简单的程序。
     程序功能:自启动服务模式运行。开机40分钟后,强制关机,并把当前时刻记录到lastTime.dat中;每次开机前读取系统时间,与lastTime.dat中的时间进行比较,若小于10分钟,则强制关机。
    为防止儿子发现服务并卸载该软件,电脑采用EWF方式进行文件保护,并且屏蔽了任务管理器和控制面板中的服务项目。

 

  程序源码如下: 

 

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

 

#define WINNT       0x11
#define WIN9X       0x12
#define EXITWINDOWS_FAILED    0x13
#define EXITWINDOWS_SUCESS    0x14
#define ADJUST_TOCKEN_SUCESS   0x15
#define ADJUST_TOCKEN_FAILED   0x15
#define ADJUST_PRIVILEGE_FAILED   0x16
#define OPENING_PROCESS_TOKEN_FAILED 0x100

 

UINT   m_nVersionType;

 

BOOL AdjustProcessTokenPrivilege()
{
    HANDLE hToken;     

    TOKEN_PRIVILEGES tkp;
 
    if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
   {
        return OPENING_PROCESS_TOKEN_FAILED;
   }
 
   if(!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid))
   {
        return ADJUST_PRIVILEGE_FAILED;
   }
 
    tkp.PrivilegeCount = 1;

    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
 
    if (GetLastError() != ERROR_SUCCESS)
    {
        return ADJUST_TOCKEN_FAILED;
    }

    return ADJUST_TOCKEN_SUCESS;
}


BOOL ExitWindowsExt(UINT nFlag, DWORD dwType)
{
   int iRetval(0);

   switch(m_nVersionType)
   {
       case WINNT:
      {
           if((iRetval=AdjustProcessTokenPrivilege()) == ADJUST_TOCKEN_SUCESS)
          {
              return ExitWindowsEx(nFlag, dwType);
          }
          else
         {
             return iRetval;
         }
         break;
      }
      case WIN9X:
      {
         return ExitWindowsEx(nFlag, dwType);
         break;
      }
   }
   return FALSE;
}

 

void CheckAndShutDown()
{
     int hour = 0;
     int minute = 0;
     time_t timer = time(NULL);
     struct tm *tb = localtime(&timer);
 
     // 开机检测是否与上次关机时间在10分钟之内,如果是,则继续关机
     FILE *fr = fopen("D://lastTime.dat", "r");
     if(fr)
     {
         fscanf(fr, "%d%d", &hour, &minute);
         fclose(fr);
     }

     int diff = (tb->tm_hour - hour) * 60 + (tb->tm_min - minute);
     if(abs(diff) < 10)
     {
         ExitWindowsExt(EWX_POWEROFF|EWX_FORCE, 0);
     }

     Sleep(40 * 60 * 1000); // 40分钟自动关机一次

     // 在关机前记录当前时间
     timer = time(NULL);
     tb = localtime(&timer);
 
     FILE *fw = fopen("D://lastTime.dat", "w");
     if(fw)
     {
         fprintf(fw, "%d %d", tb->tm_hour, tb->tm_min);
         fclose(fw);
     }
 
     // ForcePoweroff
     ExitWindowsExt(EWX_POWEROFF|EWX_FORCE, 0);
}

 


// Declare several global variables to share
// their values across multiple functions of your program.

SERVICE_STATUS          ServiceStatus;
SERVICE_STATUS_HANDLE   hStatus;


// Make the forward definitions of functions prototypes.
//


void  ServiceMain(int argc, char** argv);
void  ControlHandler(DWORD request);

// Control Handler
void ControlHandler(DWORD request)
{
     switch(request)
     { 
     case SERVICE_CONTROL_STOP:
          OutputDebugString("Monitoring stopped.");
  
          ServiceStatus.dwWin32ExitCode = 0;
          ServiceStatus.dwCurrentState = SERVICE_STOPPED;
          SetServiceStatus (hStatus, &ServiceStatus);
          return;
  
     case SERVICE_CONTROL_SHUTDOWN:
          OutputDebugString("Monitoring stopped.");
  
          ServiceStatus.dwWin32ExitCode = 0;
          ServiceStatus.dwCurrentState = SERVICE_STOPPED;
          SetServiceStatus (hStatus, &ServiceStatus);
          return;
       
     default:
     break;
    }
 
    // Report current status
    SetServiceStatus (hStatus, &ServiceStatus);
 
    return;
}

 

void ServiceMain(int argc, char** argv)

     ServiceStatus.dwServiceType = SERVICE_WIN32; 
     ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 
     ServiceStatus.dwControlsAccepted =  SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
     ServiceStatus.dwWin32ExitCode = 0; 
     ServiceStatus.dwServiceSpecificExitCode = 0; 
     ServiceStatus.dwCheckPoint = 0; 
     ServiceStatus.dwWaitHint = 0;
 
     hStatus = RegisterServiceCtrlHandler("AutoOff", (LPHANDLER_FUNCTION)ControlHandler);
     if (hStatus == (SERVICE_STATUS_HANDLE)0)
     {
            // Registering Control Handler failed
            return;
     } 
 
      // We report the running status to SCM.
     ServiceStatus.dwCurrentState = SERVICE_RUNNING;
     SetServiceStatus (hStatus, &ServiceStatus);
     CheckAndShutDown();
 
     return;
}

 

int main(int argc, char **argv)
{
      OSVERSIONINFO m_osvi;

      m_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 
      BOOL bval = GetVersionEx(&m_osvi);
 
      if(m_osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
      {
           m_nVersionType = WINNT;
      }
      else if(m_osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
      {
           m_nVersionType = WIN9X;
      } 

 

#ifdef SERVICE
      SERVICE_TABLE_ENTRY ServiceTable[2];
      ServiceTable[0].lpServiceName = "AutoOff";
      ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
 
      ServiceTable[1].lpServiceName = NULL;
      ServiceTable[1].lpServiceProc = NULL;
      // Start the control dispatcher thread for our service
      StartServiceCtrlDispatcher(ServiceTable);
#else
      CheckAndShutDown();
#endif

 

      return 0;
}

 

CheckAndShutDown()是主执行程序。
AdjustProcessTokenPrivilege()和ExitWindowsExt()是用于设置强制关机权限的,参考http://www.host01.com/article/software/cc/20060917233139326.htm

ServiceMain()和ControlHandler()是服务程序函数,参考http://www.vckbase.com/document/viewdoc/?id=1474

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值