文章目录

  • ​​0 背景​​
  • ​​1 使程序具有管理员权限​​
  • ​​2 以管理员权限打开应用​​
  • ​​3 启动非管理员权限的应用​​

0 背景

因为项目用到自动跟新,需要用主程序打开更新程序进行更新,更新完成后使用更新程序打开主程序。为了更新过程自然,因此不能使用管理员权限打开更新程序,否则会弹出对话框(是否以管理员权限打开应用),所以更新程序就是没有管理员权限的,但是主程序必须拥有管理员权限(启动时以管理员权限打开)才能直接(使用QProcess)打开其他不需要管理员权限的程序,而打开管理员权限的程序有需要调用windwos的系统API函数。经过多次尝试后,终于成功了。

1 使程序具有管理员权限

在编写的源代码文件中增加下面两个文件:

文件名:uac.manifest

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>  
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='requireAdministrator' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

文件名:res.rc

1 24 uac.manifest

在.pro文件中添加:

CONFIG(release, debug|release){#仅在release模式下,才以管理员权限运行
RC_FILE += res.rc
}

2 以管理员权限打开应用

头文件:

#ifdef Q_OS_WIN
#include <windows.h>
#endif

启动程序

#ifdef Q_OS_WIN/** 以下代码为宽字符,若改变字符集会导致编译不过,需将wstring换为string */
//临时提升管理员权限
std::wstring operate = QString("runas").toStdWString();
//文件所在的文件夹路径
std::wstring path = QCoreApplication::applicationDirPath().toStdWString();
//文件路径 F:/regSms.exe
std::wstring file= QString(QCoreApplication::applicationDirPath()+"/regSms.exe").toStdWString();
//启动程序
int ret = (int)ShellExecute(NULL,operate.c_str(),file.c_str(),NULL,path.c_str(),SW_SHOWNORMAL);
//判断启动的状态
QString sRet = QString("未知");
switch(ret)
{
case 0:
sRet = QString("内存不足");
break;
case 2:
sRet = QString("文件名错误");
break;
case 3:
sRet = QString("路径名错误");
break;
case 11:
sRet = QString("exe文件无效");
break;
case 26:
sRet = QString("发生共享错误");
break;
case 27:
sRet = QString("文件名不完全或无效");
break;
case 28:
sRet = QString("超时");
break;
case 29:
sRet = QString("DDE事务失败");
break;
case 30:
sRet = QString("正在处理其它DDE而不能完成该DDE");
break;
case 31:
sRet = QString("没有相关联的应用程序");
break;
default:
sRet = QString("未知");
break;
}
if(ret > 32)//返回值大于32表示ShellExecute执行成功
QMessageBox::information(this,G2U("提示"),G2U("执行成功:\n"));
else
QMessageBox::warning(this,G2U("警告"),G2U("执行失败【%1】!").arg(sRet));
return ;
#else
QMessageBox::warning(this,G2U("警告"),G2U("短信猫仅在windows系统下可用!"));
return ;
#endif

3 启动非管理员权限的应用

QString path;
path = QApplication::applicationDirPath() + "/updateSoftware/sql7.exe";
//路径转译
path.replace("/", "\\");
qDebug()<<"path:"<<path;
//命令或参数
QStringList arguments;
//启动并设置参数
m_process.start(path, arguments);

参考博文:

1

2