在Windows服务中使用可等待计时器

时间:2011-03-23 00:23:09

标签: c++ windows

我试图在用C ++编写的Windows服务中使用WaitableTimer来使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 个答案:

答案 0 :(得分:2)

如果它在服务之外工作,那么你的代码可能没问题。实际上我只能想到两件可能导致其表现不同的事情:

  1. 恢复可能要求服务能够“与桌面交互”。尝试在登录选项卡下的服务管理器中设置该选项,然后重新启动服务。

  2. 作为LOCAL_SYSTEM运行的服务可能无权从睡眠状态恢复。尝试自己运行服务,或专门为要运行的服务创建服务帐户。

  3. 如果您已经以特定用户身份运行该服务,那么该用户帐户可能没有足够的权限。