Chinaunix首页 | 论坛 | 博客
  • 博客访问: 465819
  • 博文数量: 724
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5010
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(724)

文章存档

2011年(1)

2008年(723)

我的朋友

分类:

2008-10-13 17:06:12

系统定时休眠
作者:



单位最近加强安全检查,除了部分服务器,下班不关机器的同事,都被罚了款。为此,我试着下载了几个自动关机的程序,但是都不好使。都是最后显示“你可以安全地关闭计算机了!”。到网上问了半天说是高级电源管理设置的问题。我折腾了半天,还是不行,为什么Windows自己的关机就可以关掉电源,而我们的程序就只能“你可以安全的关闭计算了!”。看来微软还不知道在哪里留了一手。
好在还有收获,最近发现MSDN还有这么一个函数

BOOL SetSystemPowerState(
  BOOL fSuspend,  // system state
  BOOL fForce     // forced suspension option
);
真是好东东,比关机器还好,在任何情况下都可以切断电源(这正是我想要的),也不会有讨厌的提示。

函数很简单,但直接用不好使,前面得加些罗哩八嗦的东东,所以我就进行了一下封装。

void  PERR(LPTSTR szAPI, DWORD dwLastError);
#define RTN_ERROR 13

INT SetPower()
{
	
	// TODO: Add your control notificationhandler code here
   TOKEN_PRIVILEGES tp;
    HANDLE hToken;
	LUID luid;

   LPTSTR MachineName=NULL; // pointer to machine name

	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;

}
void PERR(
    LPTSTR szAPI,       // pointer to failed API name
    DWORD dwLastError   // last error value associated with API
    )
{
    LPTSTR MessageBuffer;
    DWORD dwBufferLength;

    // 
    // TODO get this fprintf out of here!
    // 
    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;

        // 
        // Output message string on stderr
        // 
        WriteFile(GetStdHandle(STD_ERROR_HANDLE),
                  MessageBuffer,
                  dwBufferLength,
                  &dwBytesWritten,
                  NULL);

        // 
        // free the buffer allocated by the system
        // 
        LocalFree(MessageBuffer);
    }
}

注意:此函数只运行于Windows 2000/XP,并且打开了高级电源管理的休眠支持。

根据这个函数,写了个小东东,我不想让他一直运行占我的资源。于是就在计划任务里建了一个任务,只要在检查之前执行就行。呵呵!
总之没什么高深的,我也是菜鸟,如果你知道了就不要看了,希望那些爱骂人“高手”不要骂我:-)
--------------------next---------------------

"检查之前",就是早点运行程序关掉电源啊。检查过了就算你没关机器啊。 ( Jans 发表于 2003-5-12 9:08:00)
 
呵呵!没有骂的,谢谢大家这么支持! ( Jans 发表于 2003-5-12 9:04:00)
 
thanks! ( musicfan 发表于 2003-5-12 8:54:00)
 
"只要在检查之前执行就行"什么意思? ( j965829 发表于 2003-5-11 13:43:00)
 
谢谢发布给我们学习! ( xiaojin 发表于 2003-5-9 13:50:00)
 
不错不错!
确实好!
( raobo 发表于 2003-5-9 11:31:00)
 
void ShutDown( )
{
TOKEN_PRIVILEGES tkp,tkpnewbutignored;
HANDLE hdltokenhandle, hdlprocesshandle;
LUID tmpluid;
BOOL rc;
DWORD lbufferneeded;

hdlprocesshandle = GetCurrentProcess();
rc = OpenProcessToken(hdlprocesshandle,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hdltokenhandle);
rc = LookupPrivilegeValue("","SeShutdownPrivilege", &tmpluid);

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = tmpluid;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
rc = AdjustTokenPrivileges(hdltokenhandle,FALSE,&tkp,sizeof(tkpnewbutignored),&tkpnewbutignored, &lbufferneeded);
    SetSystemPowerState( false,  true);
// ExitWindowsEx(uEWXFlag,0);
}
( linjin101 发表于 2003-5-9 9:57:00)
 
我也为这待机搞了好长时间。
我不知如何通过转换键盘sleep键的消息实现....???
最简单的待机:
#include 
void ShutDown( );
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{  
WNDCLASS   wndclass;

wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
     
if( IDYES == MessageBox (NULL,TEXT("是否待机"),TEXT("待机"),MB_ICONQUESTION | MB_YESNO))
ShutDown( );
     
     return 0;
}
( linjin101 发表于 2003-5-9 9:57:00)
 
只要是自己不会的就是好东西,无论多么的浅显! ( ckp 发表于 2003-5-9 0:20:00)
 
这个函数挺好用 ( renqiang1028 发表于 2003-5-8 23:30:00)
 
.......................................................

--------------------next---------------------

阅读(188) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~