Использование таймера ожидания из службы Windows - PullRequest
0 голосов
/ 23 марта 2011

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

Код, который я использую для настройки ожидаемого таймера, выглядит следующим образом (вызов 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);
}

1 Ответ

2 голосов
/ 23 марта 2011

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...