Tuesday, September 28, 2010

[Solution] QProcess::startDetached cannot start process that requires elevated privileges in Microsoft Windows Vista, Windows Server 2008 or Windows 7

When running under Microsoft Windows Vista, Windows Server 2008 or Windows 7 with User Account Control (UAC) enabled, the following code always fails if starting a program that requires elevated privileges (it can be, for example, a setup program):

    QString exeFileName;

/.../

if (!QProcess::startDetached(exeFileName))
{
// error handling
}


The inner reason for this failure is that QProcess::startDetached method under Windows internally calls CreateProcess function. CreateProcess called from a non-elevated process fails with ERROR_ELEVATION_REQUIRED if it tries to start an executable that requires elevation.

Corresponding error report in Qt Bug Tracker was rejected because it "sounds like a reasonable limitation of QProcess".

Below is a possible solution for this problem. In short: QProcess::startDetached is replaced with ShellExecute function.

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

/.../

QString exeFileName;

/.../


#ifdef Q_OS_WIN
int result = (int)::ShellExecuteA(0, "open", exeFileName.toUtf8().constData(), 0, 0, SW_SHOWNORMAL);
if (SE_ERR_ACCESSDENIED == result)
{
// Requesting elevation
result = (int)::ShellExecuteA(0, "runas", exeFileName.toUtf8().constData(), 0, 0, SW_SHOWNORMAL);
}
if (result <= 32)
{
// error handling
}
#else
if (!QProcess::startDetached(exeFileName))
{
// error handling
}
#endif

2 comments: