请指点

解决方案 »

  1.   

    给你个例子:#define RTN_ERROR 13
    int SetPower(BOOL bSuspend,BOOL bForce)       //主要功能函数
    {     
    TOKEN_PRIVILEGES tp;    
    HANDLE hToken;
    LUID luid;
    LPTSTR MachineName=NULL;  if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken ))
        {
            return RTN_ERROR;
        }
    if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid))
    {
            return RTN_ERROR;
        }
    tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),NULL, NULL );
    SetSystemPowerState(bSuspend,bForce);

    return 0;
    }其中,SetSystemPowerState是调用睡眠或休眠的函数,第一个参数bSuspend为TRUE时,执行睡眠,为FALSE时执行休眠;第二个参数bForce是决定是否强制执行。在NT中直接调用SetSystemPowerState函数是不起作用的,要先取得权限,所以在SetSystemPowerState之前的代码是取得权限之用。
      

  2.   

    至于唤醒,我是重载了WindowProc:
    HANDLE hTimer=NULL;
    LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
    {
    // TODO: Add your specialized code here and/or call the base class
    switch(message)
    {
    case WM_POWERBROADCAST:
    switch(wParam)
    {
    case PBT_APMSUSPEND:
    hTimer=::CreateWaitableTimer(NULL,TRUE,"WaitForResume");
    if(!hTimer)
    {
    MessageBox("Fail to create waitable timer!");
    //break;
    }
    hTimer=OpenWaitableTimer(TIMER_ALL_ACCESS,TRUE,"WaitForResume");
    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart=nCounter*1000*1000*(-10);
    if(!::SetWaitableTimer(hTimer,&liDueTime,0,NULL,NULL,TRUE))
    {
    MessageBox("Fail to set waitable timer!");
    break;
    } if(SetPower(TRUE,TRUE)==RTN_ERROR)
    {
    DWORD Er=GetLastError();
    CString bfr;
    bfr.Format("%d",Er);
    MessageBox("Can not suspend!"+bfr);
    }
    break;
    default:
    break;
    }
    break;
                      }
             default:
                    break;
    }
    return CDialog::WindowProc(message, wParam, lParam);
    }其中,nCounter是你想让系统唤醒的时间。
      

  3.   

    标题     Windows 2000/XP 下实现休眠    zhucde(原作)  
      
    关键字     休眠 
      
    实现休眠功能很简单,只要在任意想要执行的地方执行如下给出的休眠函数SetPower()就行,其实休眠很简单,只需要API:SetSystemPowerState()就行,就如关机/注销/重启一样,只需要ExitWindowEx(),但这些API可以直接用在98下,却不能用在2000/XP中,因为这里牵涉到了用户权限,没有权限是不能进行这些操作的,所以,首先要取得权限,下面给出代码:#define RTN_ERROR 13void  PERR(LPTSTR szAPI, DWORD dwLastError)   //休眠时调用到的一个函数,用来                                                                             ////记录休眠中遇到的错误{
        LPTSTR MessageBuffer;
        DWORD dwBufferLength;
        fprintf(stderr,"%s error! (rc=%lu)\n", szAPI, dwLastError);    if(dwBufferLength=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                        FORMAT_MESSAGE_FROM_SYSTEM,
                                        NULL,
                                        dwLastError,
                                        LANG_NEUTRAL,
                                        (LPTSTR) &MessageBuffer,
                                        0,
                                        NULL))
        {        DWORD dwBytesWritten;         WriteFile(GetStdHandle(STD_ERROR_HANDLE),
                      MessageBuffer,
                      dwBufferLength,
                      &dwBytesWritten,
                      NULL);
            LocalFree(MessageBuffer);
        }
    }
    INT SetPower()有       //主要功能函数
    {
     
     
       TOKEN_PRIVILEGES tp;
        HANDLE hToken;
     LUID luid;   LPTSTR MachineName=NULL;  if(!OpenProcessToken(GetCurrentProcess(),         ////////从这里////////////////////////////
                            TOKEN_ADJUST_PRIVILEGES,
                            &hToken ))
        {
            PERR("OpenProcessToken", GetLastError() );
            return RTN_ERROR;
        }    if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid))    {
            PERR("LookupPrivilegeValue", GetLastError() );
            return RTN_ERROR;
        }    tp.PrivilegeCount           = 1;
        tp.Privileges[0].Luid       = luid;
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;    AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
                                    NULL, NULL );    ////////////////到这里,是取得权限//////////////////////        SetSystemPowerState(FALSE,TRUE);       
      return 0;} 这样,在任意需要休眠的时候调用SetPower();即可休眠,但是有一点要注意:必须打开了高级电源管理的休眠支持。 
      

  4.   

    谢谢楼上几位,结贴时会给分的。不过我的真正的意思不是操作系统休眠,是硬盘停止转动,但是操作系统依然工作。就如同电源管理中设置硬盘休眠后,几分钟不进行硬盘读写操作便会休眠。这方面的资料似乎不多。一定用到DDK,或者写VXD吗?呵呵。
      

  5.   

    只要操作系统在工作时,硬盘就不可能停止转动。你所说的“电源管理中设置硬盘休眠后,几分钟不进行硬盘读写操作便会休眠”,其实这是睡眠状态(Suspend To Ram),部分系统设备仍在工作,只是进入了低速运行,这种状态在BIOS中叫做S3状态。而要硬盘停止转动的状态,是叫休眠状态(Suspend To Disk),这时系统设备基本上都停止工作,这在BIOS里叫做S4状态。而S5就是关机。
      

  6.   

    谢谢zkxz兄的解答,不过还是没有理解我的问题。
    WIN2K关机时有5个选项:注销、关机、重启、等待、休眠。zkaz兄所言S3,是等待状态,或称之待机状态,是最低功耗的开电状态,动动鼠标键盘就会唤醒,S3状态不能掉电。休眠是S4状态,WINDOWS将内存的东东都写入硬盘然后关机,重上电时将硬盘数据恢复至内存,所以启动快能恢复至休眠时的工作状态,S4是可以掉电的。S5就不用说了。
    但是,但是,但是楼上的各位大大啊,为什么不能理解我的问题的真正含义啊,是我的表达太有问题?
    我说的是硬盘休眠,一般指非主硬盘停止转动。而主硬盘可能仍在工作。zkxz兄所言“只要操作系统在工作时,硬盘就不可能停止转动。”其实是不对的。
    请大大们注意,我的问题与操作系统的休眠无关!!!
    在WIN2K中不允许直接使用中断,使用DeviceIoControl也是不能实现的。谢谢楼上各位,请明白我问题者继续,分不够再加,呵呵。