在Qt中获取系统用户名

28

有没有跨平台的方法在Qt C ++程序中获取当前用户名?

我搜索了互联网和文档以寻找解决方案,但我只能找到依赖于操作系统的系统调用。

6个回答

52

其实我几天前就在考虑这个问题,得出了以下不同的替代方案,每个方案都有自己的权衡:

使用qgetenv环境变量。

这种解决方案的优点是非常容易实现。缺点是,如果环境变量被设置为其他内容,那么这种解决方案就完全不可靠。

#include <QString>
#include <QDebug>

int main()
{
    QString name = qgetenv("USER");
    if (name.isEmpty())
        name = qgetenv("USERNAME");
    qDebug() << name;
    return 0;
}

使用QStandardPaths获取主目录位置

这种方法的好处是相对容易实现,但如果在用户主目录中使用不同的用户名和“条目”,它可能会变得不可靠。

#include <QStandardPaths>
#include <QStringList>
#include <QDebug>
#include <QDir>

int main()
{
    QStringList homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
    qDebug() << homePath.first().split(QDir::separator()).last();
    return 0;
}

运行外部进程并使用平台特定的API

这可能是最难实现的,但另一方面,这似乎是最可靠的,因为它不像环境变量或主目录技巧那样容易被应用程序更改。在Linux上,您可以使用QProcess来调用通常的whoami命令,而在Windows上,您将使用GetUserName WinAPI来实现此目的。

#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

int main(int argc, char **argv)
{
// Strictly pseudo code!
#ifdef Q_OS_WIN
    char acUserName[MAX_USERNAME];
    DWORD nUserName = sizeof(acUserName);
    if (GetUserName(acUserName, &nUserName))
        qDebug << acUserName;
    return 0;
#elif Q_OS_UNIX
    QCoreApplication coreApplication(argc, argv);
    QProcess process;
    QObject::connect(&process, &QProcess::finished, [&coreApplication, &process](int exitCode, QProcess::ExitStatus exitStatus) {
        qDebug() << process.readAllStandardOutput();
        coreApplication.quit();
    });
    process.start("whoami");
    return coreApplication.exec();
#endif
}

总结: 就个人而言,我会选择最后一种变体,因为虽然它最难实现,但这是最可靠的。


你的第一个“if”是大写的。 - migas
@migas:谢谢,我的回答最初被投票降到了-1,我真的不明白为什么,因为我认为我已经尽力回答了。虽然如此,这对于 Stack Overflow 来说是有用的知识。感谢你的提问。 :-) - László Papp
脱帽致敬,远远超出我的期望。由于我的程序性质和它将要运行的受控环境,我会选择 qgetenv 选项,因为它更简单易懂。家庭环境选项,在我看来,并不是一个实际的选项,因为家是心灵栖息的地方(或者用户定义的地方)。但就答案的质量而言,这个选项肯定是被批准的。记录一下,我既没有测试第二个解决方案也没有测试第三个解决方案,但它们肯定是可靠的。 - migas
在Linux上,您会使用QProcess和whoami吗?但我不会。我会使用getlogin_r函数。;-) - Greenflow
GetUserName有一个Unicode版本(GetUserNameW),你应该使用它。使用ANSI版本的GetUserNameA会浪费资源,而且可能无法产生期望的结果。 - IInspectable
显示剩余2条评论

7

2
如果我要使用环境变量,我认为我更喜欢使用qgetenv,因为这是Qt的做法。 - migas
1
@migas:不仅如此,它也不可靠。 - László Papp
我认为qgetenv也比getenv更好。 :) - jd6

3
在QT5及以上版本中,可以进行以下操作:
QString userName = QDir::home().dirName();

`QDir::home()`返回用户的主目录。


该函数用于获取用户的主目录。

1
需要注意的是,用户主目录并不总是与用户名相同。 - Linkan

2
你可以使用qEnvironmentVariable
QString sysUsername = qEnvironmentVariable("USER");
if (sysUsername.isEmpty()) sysUsername = qEnvironmentVariable("USERNAME");

0

你也可以像这样使用QProcessEnvironment

QProcessEnvironmentenv = QProcessEnvironment::systemEnviroment();
QString username = env.value("USER");

-1

使用Qt可以获取当前Windows用户名的方法。以下是方法:

mainwindow.ui 这是表单UI

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QDir>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->getUser();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::getUser()
{
    QProcess *username = new QProcess();
    QStringList cmdParamaters, split;
    QString clean1, clean2, clean3,userName;
    int cutOff, strLen;

    cmdParamaters << "/c"<<"\"%USERPROFILE%\"";
    username->setProcessChannelMode(QProcess::MergedChannels);
    username->start("cmd.exe",cmdParamaters);
    username->waitForFinished();

    QString vusername (username->readAllStandardOutput());
    cutOff = vusername.indexOf("'", 1);
    ui->label_2->setText(vusername);

    clean1 = vusername.left(cutOff);
    ui->label_3->setText(clean1);

    clean2 = clean1.remove(0,3);
    strLen = clean2.length();
    ui->label_4->setText(clean2);

    clean3 = clean2.left(strLen-2);
    split = clean3.split("\\");

    userName = split[2]; //This is the current system username
    ui->label_5->setText(userName);
    delete username;
}

输出: 代码输出


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接