192上位机VC MFC实现电脑的重启关机注销功能
192上位机VC MFC实现电脑的重启关机注销功能 功能展示 自己电脑的关机注销重启可以通过鼠标来操作完成也可以通过代码编程控件,比如很多软件安装完成后都有重启电脑功能,我们当前例程也自己编程实现电脑的关机,重启,注销功能,效果如图。由于功能原因无法程序演示及录制教程,可以下载例程运行看效果; 要点提示 电脑的关机重启及注销只要调用一个函数ExitWindowsEx()便可,但个别系统还得合应用程序获得相关权限才能实现这些功能,比如微软的2000系统。所以为使功能健全,我们还得调用OpenProcessToken()LookupPrivilegeValue() AdjustTokenPrivileges()三个函数,获得实现这三功能的操作权限; ExitWindowsEX()函数用来退出、重启或注销系统; 函数原型编辑 1.BOOLExitWindowsEx( UINT uFlags, // 关闭参数 DWORD dwReserved // 系统保留,一般取0 参数编辑 uFlags 指定关闭的类型。此参数必须有下列值的组合: EWX_FORCE 强制终止进程。当此标志设置,Windows不会发送消息WM_QUERYENDSESSION和WM_ENDSESSION的消息给目前在系统中运行的程序。这可能会导致应用程序丢失数据。因此,你应该只在紧急情况下使用此标志。 EWX_LOGOFF 关闭所有进程,然后注销用户。 EWX_POWEROFF 关闭系统并关闭电源。该系统必须支持断电。 Windows要求: Windows NT中调用进程必须有 SE_SHUTDOWN_NAME 特权。 Windows 9X中:可以直接调用。 EWX_REBOOT 关闭系统,然后重新启动系统。 Windows要求: Windows NT中:调用进程必须有SE_SHUTDOWN_NAME特权。 Windows 9X中:可以直接调用。 EWX_SHUTDOWN 关闭系统,安全地关闭电源。所有文件缓冲区已经刷新到磁盘上,所有正在运行的进程已经停止。 Windows要求: Windows NT中:调用进程必须有SE_SHUTDOWN_NAME特权。 Windows 9X中:可以直接调用。 dwReserved 系统保留,这参数被忽略。一般取0。 返回值:如果函数成功,返回值为非零。如果函数失败,返回值是零。想获得更多错误信息,请调用GetLastError()函数 2.OpenProcessToken函数用来打开与进程相关联的访问令牌 函数原型:BOOLOpenProcessToken( __in HANDLE ProcessHandle, //要修改访问权限的进程句柄 __in DWORD DesiredAccess, //指定你要进行的操作类型 __out PHANDLE TokenHandle);//返回的访问令牌指针 第一参数是要修改访问权限的进程句柄;第三个参数就是返回的访问令牌指针;第二个参数指定你要进行的操作类型,如要修改访问令牌的特权,我们要指定第二个参数为TOKEN_ADJUST_PRIVILEGES = &H20(其它一些参数可参考Platform SDK)。通过这个函数我们就可以得到当前进程的访问令牌的句柄(指定函数的第一个参数为GetCurrentProcess()就可以了)。 3. 函数原型:BOOL LookupPrivilegeValue(LPCTSTRlpSystemName,LPCTSTR lpName,PLUID lpLuid); 第一个参数表示所要查看的系统,本地系统直接用NULL 第二个参数指向一个以零结尾的字符串,指定特权的名称,如在WinNT h头文件定义。例如,此参数可指定常数,se_security_name,或其对应的字符串,“sesecurityprivilege ";。 第三个参数用来接收所返回的制定特权名称的信息 4. AdjustTokenPrivileges ()这个函数启用或禁止指定访问令牌的特权。 启用或禁用特权一个有TOKEN_ADJUST_PRIVILEGES访问的访问令牌. BOOL AdjustTokenPrivileges( HANDLE TokenHandle, //包含特权的句柄 BOOL DisableAllPrivileges,//禁用所有权限标志 PTOKEN_PRIVILEGES NewState,//新特权信息的指针(结构体) DWORD BufferLength, //缓冲数据大小,以字节为单位的PreviousState的缓存区(sizeof) PTOKEN_PRIVILEGES PreviousState,//接收被改变特权当前状态的Buffer PDWORD ReturnLength //接收PreviousState缓存区要求的大小 参数kenHandle:包含要修改特权的访问令牌的标识(句柄).这个句柄必须有TOKEN_ADJUST_PRIVILEGES访问令牌.如果PreviousState不是NULL,这个句柄还必须有TOKEN_QUERY访问特权. DisableAllPrivileges:标志这个函数是否禁用该令牌的所有特权.如果为TRUE,这个函数禁用所有特权,NewState参数无效.如果为假,以NewState参数指针的信息为基础来修改特权. NewState:一个TOKEN_PRIVILEGES结构体的指针指定了一组特权和他们的属性. 如果参数DisableAllPrivileges为FALSE,AdjustTokenPrivileges 启用或禁用这些令牌的特权. 如果你给一个特权设置了SE_PRIVILEGE_ENABLED的属性,这个函数将启动特权,否则禁用特权. 如果DisableAllPrivileges为TRUE,这个参数无效. BufferLength:标志参数PreviousState指针以字节大小缓存区(sizeof). 如果参数PreviousState是NULL,这个参数可以为NULL. PreviousState:这个函数填充一个TOKEN_PRIVILEGES结构体它包括该函数修改之前任何特权状态.这个参数可以为NULL. 如果指定的缓冲区太小,无法收到完整的修改权限列表,这个函数失败并不会修改任何特权. 这个函数设置了一个 拥有修改权限完成列表参数ReturnLength的字节数 的指针变量[结果的Buffer] ReturnLength:接收 参数PreviousState的缓存区指针的 字节大小 的 变量指针(长度指针). 如果PreviousState为NULL,这个参数可以为NULL 实现功能 1.新建基于对话框的应用程序 2.拖拽关机,重启,注销三个按钮关联函数,再添加自定义函数GetPrivilege()在程序初始化时调用此函数进行提权操作; - void CGkbc8Dlg::GetPrivilege()//获得权限
- {
- static HANDLE hToken;
- static TOKEN_PRIVILEGES tp;
- static LUID luid;
- OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken);
- LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid);
- tp.PrivilegeCount =1;
- tp.Privileges [0].Luid =luid;
- tp.Privileges [0].Attributes =SE_PRIVILEGE_ENABLED;
- AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL, NULL);
- }
- void CGkbc8Dlg::OnShutdown() //关机
- {ExitWindowsEx(EWX_POWEROFF,0);}
- void CGkbc8Dlg::OnReboot() //重启
- {ExitWindowsEx(EWX_REBOOT,0);}
- void CGkbc8Dlg::OnLogoff() //注销
- {ExitWindowsEx(EWX_LOGOFF,0);}
复制代码例程功能特殊无法视频演示,学者可自行运行程序查看效果及学习代码功能
|