(2)在工作组环境中无法直接以该用户账号从控制机登录被控机,需要在控制机上创建与被控机上一致的用户账号(用户名和密码都需相同),可预先通过“计算机管理”完成,也可在调用关机代码前临时通过下面的代码来创建:
NET_API_STATUS retStatus = 0;
DWORD dwError = 0;
USER_INFO_1 structUserInfo;
ZeroMemory(&structUserInfo, sizeof(structUserInfo));
structUserInfo.usri1_name = szUserName;
structUserInfo.usri1_password= szPassword;
structUserInfo.usri1_priv = USER_PRIV_USER;
structUserInfo.usri1_flags = UF_NORMAL_ACCOUNT;
retStatus = NetUserAdd(NULL, 1, (LPBYTE)(&structUserInfo), &dwError); //创建用户
//将该用户加到"Administrators"组
_LOCALGROUP_MEMBERS_INFO_3 memberUser;
memberUser.lgrmi3_domainandname = structUserInfo.usri1_name;
retStatus = NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)(&memberUser), 1);
在调用关机代码后如果要删除上面所创建的用户可通过下面代码完成:
NetUserDel(NULL,structUserInfo.usri1_name);
(3)在控制机和被控机的“组策略”中找到“本地策略”的“安全选项”的“网络访问:本地账号的共享和安全模式”,设置为“经典-本地用户以自己的身份验证”。
(4)如果在控制机上已用上面建立的用户账号登录,此时可直接调用InitiateSystemShutdown函数远程关机,否则先要通过下面代码登录:
// LogonUser函数接受登录信息并返回有效登入的安全性访问令牌。
LogonUser(m_strUserName,strMachineName,m_strPassword,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hLogonToken);
// ImpersonateLoggedOnUser函数接收LogonUser的安全性访问令牌,并将该令牌用到目前的执行中。
ImpersonateLoggedOnUser( hLogonToken );
(5)调用InitiateSystemShutdown函数远程关机
InitiateSystemShutdown(strMachineName,"关机!",30,TRUE,FALSE);
三、结语
本文实现了局域网中的远程开机功能和有客户端无客户端两种方式下的关机功能,在此基础上还可根据需要进行功能扩展。本程序在WindowsXP操作系统下用VC6.0或VS.NET都能调试通过,并投入使用。
|