QT使用WindowsAPI NetUserAdd创建系统用户

首先,放上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 );

如图: 

好了,代码全部完成!现在编译测试一下:

 

用户添加成功!

需要注意的是:

一、密码是否能像我图中那样设置简单密码,还取决于系统中的密码策略设置:

如果密码不符合这里的设置,那么用户就会添加失败!

二、服务器地址可以是计算机名,也可以是IP。如果不填,那默认就是本机!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

skyyx2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值