2008年(909)
分类:
2008-05-06 21:42:25
下载示例源代码
单位最近加强安全检查,除了部分服务器,下班不关机器的同事,都被罚了款。为此,我试着下载了几个自动关机的程序,但是都不好使。都是最后显示“你可以安全地关闭计算机了!”。到网上问了半天说是高级电源管理设置的问题。我折腾了半天,还是不行,为什么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); } }