2011-03-23 2 views
0

Я пытаюсь использовать WaitableTimer в службе Windows, написанной на C++, чтобы вывести компьютер из Windows XP из режима ожидания/ожидания, но я не могу заставить его работать. Я копирую/вставляю код, который я использую в сервисе, в автономное приложение, и это отлично работает. Есть ли какой-то шаг, который мне не хватает, чтобы заставить его работать в рамках службы?Использование ожидающего таймера из службы Windows

код, я использую, чтобы настроить waitable таймер следующим образом (вызов UpdateWaitableTimer() происходит в потоке, петлями на неопределенный срок):

void UpdateWaitableTimer(job_definition *jobdef) 
{ 
    HANDLE existingHandle; 
    try 
    { 
     if (jobdef->JobType == JOB_TYPE_SCAN) 
     { 
      char szTimerName[MAX_PATH]; 
      sprintf_s(szTimerName, MAX_PATH, "Timer_%I64d", jobdef->JobID); 

      existingHandle = OpenWaitableTimer(TIMER_ALL_ACCESS, TRUE, szTimerName); 


      if (existingHandle != NULL) 
      { 

       // A timer handle already exists for this job, so cancel it 
       CancelWaitableTimer(existingHandle); 
      } 
      else 
      { 

       // No timer handle exists, create one 
       existingHandle = CreateWaitableTimer(NULL, TRUE, szTimerName); 
      } 

      if (jobdef->JobStatus != JOB_STATUS_SCHEDULED) 
      { 

       // This job was cancelled, so close the handle 
       CloseHandle(existingHandle); 
      } 
      else 
      { 

       time_t now = time(NULL); 
       time_t dt = jobdef->JobScheduleTime; 

       while(dt < now) 
       { 
        dt += 86400; 
       } 

       // Get a FILETIME one minute before 
       FILETIME utcFileTime = GetTimestamp(dt - 60); 

       // Convert to LARGE_INTEGER 
       LARGE_INTEGER dueTime; 
       dueTime.HighPart = utcFileTime.dwHighDateTime; 
       dueTime.LowPart = utcFileTime.dwLowDateTime; 

       SYSTEMTIME st; 
       FILETIME *ft = &utcFileTime; 
       FileTimeToSystemTime(ft, &st); 
       LogRelease(false, "Setting Timer for scheduled job: %02d/%02d/%d %02d:%02d:%02d", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond); 


       if(SetWaitableTimer(existingHandle, &dueTime, 0, NULL, NULL, TRUE)) 
       { 
        if(GetLastError() == ERROR_NOT_SUPPORTED) 
        { 
         LogRelease(false, "Resume from sleep/stand-by feature not supported on this operating system."); 
        } 
       } 
       else 
       { 

        LogError(false, "Could not create timer. Error: %d", GetLastError()); 
       } 
      } 
     } 
    } 
    catch(...) 
    { 
     LogError(false, "An exception occured while updating waitable timer for job %I64d", jobdef->JobID); 
    } 

    LogRelease(false, "Finished Updating Waitable Timer [Job:%I64d]", jobdef->JobID); 
} 

ответ

2

Если она работает вне службы, то ваш код вероятно, прекрасен. Есть действительно только две вещи, которые я могу думать о том, что может привести к ее вести себя по-разному:

  1. Возобновление может потребоваться обслуживание, чтобы иметь возможность «взаимодействовать с рабочим столом.» Попробуйте установить этот параметр в диспетчере служб на вкладке входа в систему и перезапустите службу.

  2. У служб, работающих как LOCAL_SYSTEM, возможно, не будет прав на возобновление сна. Попробуйте запустить службу как самостоятельно или создайте учетную запись службы, специально предназначенную для запуска службы.

Если вы уже используете службу в качестве конкретного пользователя, возможно, у этой учетной записи недостаточно прав.

Смежные вопросы