首先,放上NetUserAdd这个API的官方文档地址:NetUserAdd function (lmaccess.h) - Win32 apps | Microsoft Docs
下面是微软官方给的C++示例代码(注意,示例代码里有错误!):
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")
#include <stdio.h>
#include <windows.h>
#include <lm.h>
int wmain(int argc, wchar_t *argv[])
{
USER_INFO_1 ui;
DWORD dwLevel = 1;
DWORD dwError = 0;
NET_API_STATUS nStatus;
if (argc != 3)
{
fwprintf(stderr, L"Usage: %s \\\\ServerName UserName\n", argv[0]);
exit(1);
}
//
// Set up the USER_INFO_1 structure.
// USER_PRIV_USER: name identifies a user,
// rather than an administrator or a guest.
// UF_SCRIPT: required
//
ui.usri1_name = argv[2];
ui.usri1_password = argv[2];
ui.usri1_priv = USER_PRIV_USER;
ui.usri1_home_dir = NULL;
ui.usri1_comment = NULL;
ui.usri1_flags = UF_SCRIPT;
ui.usri1_script_path = NULL;
//
// Call the NetUserAdd function, specifying level 1.
//
nStatus = NetUserAdd(argv[1],
dwLevel,
(LPBYTE)&ui,
&dwError);
//
// If the call succeeds, inform the user.
//
if (nStatus == NERR_Success)
fwprintf(stderr, L"User %s has been successfully added on %s\n",
argv[2], argv[1]);
//
// Otherwise, print the system error.
//
else
fprintf(stderr, "A system error has occurred: %d\n", nStatus);
return 0;
}
再次提醒,上面的示例代码虽然是微软官方给的,但有错误且不完善,不要直接使用!
QT虽然底层就是C++,而且也支持C++代码,但有些地方仍需要处理!比如QT默认的文本类型QString,C++是没有的,像示例代码中的wchar_t类型和QString就需要进行转换。。
新建项目,选择构建套件(Kits)
新建一个项目,这里项目取名叫:adduser
开发Windows程序,QT常用的有MSVC和MinGW,推荐使用MinGW,如图:
本文内容也是基于MinGW!
.pro文件
双击打开adduser.pro文件:
在右侧窗口中,添加一行:
LIBS += -lnetapi32
如图:
注意,官方的示例代码:
#pragma comment(lib, "netapi32.lib")
这是MSVC才支持的写法,MinGW不支持!
.h头文件
导入头文件:
#include <stdio.h>
#include <windows.h>
#include <lm.h>
#include "QMessageBox"
定义函数:
wchar_t* QStringToWchar(QString qStr); //QString转换为wchar_t类型
int adduser(wchar_t* Server, wchar_t * User,wchar_t * Password); //添加用户
如图:
.cpp文件
cpp文件中的函数代码:
wchar_t* MainWindow::QStringToWchar(QString qStr) //QString转换为wchar_t类型
{
return (wchar_t*)reinterpret_cast<const wchar_t *>(qStr.utf16());
}
int MainWindow::adduser(wchar_t * Server,wchar_t * User,wchar_t * Password)
{
USER_INFO_1 ui;
DWORD dwLevel = 1;
DWORD dwError = 0;
NET_API_STATUS nStatus;
ui.usri1_name = User;
ui.usri1_password = Password;
ui.usri1_priv = USER_PRIV_USER; //这里设置成其它无效,比如USER_PRIV_ADMIN
ui.usri1_home_dir = NULL;
ui.usri1_comment = NULL;
ui.usri1_flags = UF_NORMAL_ACCOUNT | UF_SCRIPT | UF_DONT_EXPIRE_PASSWD; //密码永不过期
ui.usri1_script_path = NULL;
nStatus = NetUserAdd(Server, dwLevel, (LPBYTE)&ui, &dwError); //调用WindowsAPI添加用户
switch (nStatus) { //判断返回值,给出相应的提示
case NERR_Success: //0
QMessageBox::information(NULL,"成功","用户:" + QString::fromStdWString(User) + " 添加成功!");
break;
case NERR_UserExists: //2224
QMessageBox::warning(NULL,"失败","用户:" + QString::fromStdWString(User) + " 已存在!");
return 1;
case ERROR_ACCESS_DENIED: //5
QMessageBox::warning(NULL,"失败","没有访问权限!");
return 1;
case NERR_InvalidComputer: //2351
QMessageBox::warning(NULL,"失败","计算机名或IP无效!");
return 1;
case NERR_NotPrimary: //2226
QMessageBox::warning(NULL,"失败","该操作只允许在域的主域控制器上进行!");
return 1;
case NERR_GroupExists: //2223
QMessageBox::warning(NULL,"失败","用户组已存在!");
return 1;
case NERR_PasswordTooShort: //2245
QMessageBox::warning(NULL,"失败","密码不符合规范!");
return 1;
default:
QMessageBox::warning(NULL,"失败","未知错误!");
return 1;
}
//给刚才添加用户,设置权限组
_LOCALGROUP_MEMBERS_INFO_3 gi;
gi.lgrmi3_domainandname = ui.usri1_name;
nStatus = NetLocalGroupAddMembers(NULL, L"Users", 3, (LPBYTE)&gi, 1); //调用WindowsAPI将刚才添加的用户,设置成“Users”权限
switch (nStatus) {
case NERR_Success:
fwprintf(stderr, L"设置用户组成功!\n",User); //权限组设置成功就不弹出对话框提示了,太烦
break;
case NERR_GroupNotFound: //2220
QMessageBox::warning(NULL,"失败","指定的用户组不存在!");
return 1;
case ERROR_ACCESS_DENIED: //5
fwprintf(stderr, L"设置用户组失败,无权访问!\n");
QMessageBox::warning(NULL,"失败","设置用户组失败,无权访问!");
return 1;
case ERROR_NO_SUCH_MEMBER:
fwprintf(stderr, L"指定的一个或多个成员不存在!\n");
QMessageBox::warning(NULL,"失败","指定的一个或多个成员不存在!");
return 1;
case ERROR_MEMBER_IN_ALIAS:
fwprintf(stderr, L"指定的一个或多个成员已经是本地组成员!\n");
QMessageBox::warning(NULL,"失败","指定的一个或多个成员已经是本地组成员!");
return 1;
case ERROR_INVALID_MEMBER:
fwprintf(stderr, L"帐户类型无效!\n");
QMessageBox::warning(NULL,"失败","帐户类型无效!");
return 1;
default:
fwprintf(stderr, L"未知错误!\n");
QMessageBox::warning(NULL,"失败","未知错误!");
return 1;
}
return 0;
}
上面的代码有不少可以优化的地方,这里主要做用法展示,就不去纠结它们了。
UI界面
现在关键的代码已经完成,创建一个UI界面来测试一下:
拖入几个控件:Label、Line Edit、Push Button,并修改它们的文本,如图:
右键点击“添加用户” 按钮,选择“转到槽”,选择 clicked() 确定:
添加如下代码:
wchar_t *Server = QStringToWchar(ui->lineEdit->text());
wchar_t *User = QStringToWchar(ui->lineEdit_2->text());
wchar_t *Password = QStringToWchar(ui->lineEdit_3->text());
adduser( Server, User, Password );
如图:
好了,代码全部完成!现在编译测试一下:
用户添加成功!
需要注意的是:
一、密码是否能像我图中那样设置简单密码,还取决于系统中的密码策略设置:
如果密码不符合这里的设置,那么用户就会添加失败!