Como señaló Tamás, debe iniciar un nuevo proceso con derechos elevados. Busqué mucho en el pasado, pero no encontré ninguna manera de elevar los derechos del proceso actual.
Digamos que su aplicación principal es App1.exe y luego llama a un proceso secundario App2.exe que requiere derechos elevados.
A. Puede incrustar un manifiesto en su App2.exe pero la forma más simple es crear un archivo de manifiesto [un archivo de texto] llamado App2.exe.manifest con el siguiente contenido y ponerlo en el mismo directorio que App2.exe. Nota: !! Por extraño que parezca, si el nombre de su aplicación no es App2.exe sino App2_install.exe o App2_setup.exe (es decir, si el nombre de la aplicación contiene la "instalación" o "configuración") aparecerá un cuadro de diálogo UAC automáticamente en Windows Vista/Windows 7 y pedirá derechos elevados incluso si no hay un archivo manifiesto !! Esta es una muestra del archivo de manifiesto:
<?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>
B. Usted puede usar un código como el siguiente en APP1.EXE para lanzar el App2.exe
QString AppToExec = qApp->applicationDirPath() + "/App2.exe";
// Put any required parameters of App2.exe to AppParams string
QString AppParams = "";
if (0 != genWin32ShellExecute(AppToExec,
"", // default verb: "open" or "exec"
AppParams,
false, // run hidden
true)) // wait to finish
{
// (...) handle error
}
. ..y, finalmente, este es el código de la función genWin32ShellExecute Win32() creé para poner en marcha un proceso o abrir un documento utilizando QT en un Win32 O/S:
Header:
#ifdef Q_OS_WIN // Implement genWin32ShellExecute() especially for UAC
#include "qt_windows.h"
#include "qwindowdefs_win.h"
#include <shellapi.h>
int genWin32ShellExecute(QString AppFullPath,
QString Verb,
QString Params,
bool ShowAppWindow,
bool WaitToFinish);
#endif
CPP:
// Execute/Open the specified Application/Document with the given command
// line Parameters
// (if WaitToFinish == true, wait for the spawn process to finish)
//
// Verb parameter values:
// "" The degault verb for the associated AppFullPath
// "edit" Launches an editor and opens the document for editing.
// "find" Initiates a search starting from the specified directory.
// "open" Launches an application. If this file is not an executable file, its associated application is launched.
// "print" Prints the document file.
// "properties" Displays the object's properties.
//
// Ret: 0 = success
// <0 = error
#ifdef Q_OS_WIN
int genWin32ShellExecute(QString AppFullPath,
QString Verb,
QString Params,
bool ShowAppWindow,
bool WaitToFinish)
{
int Result = 0;
// Setup the required structure
SHELLEXECUTEINFO ShExecInfo;
memset(&ShExecInfo, 0, sizeof(SHELLEXECUTEINFO));
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
if (Verb.length() > 0)
ShExecInfo.lpVerb = reinterpret_cast<const WCHAR *>(Verb.utf16());
ShExecInfo.lpFile = NULL;
if (AppFullPath.length() > 0)
ShExecInfo.lpFile = reinterpret_cast<const WCHAR *>(AppFullPath.utf16());
ShExecInfo.lpParameters = NULL;
if (Params.length() > 0)
ShExecInfo.lpParameters = reinterpret_cast<const WCHAR *>(Params.utf16());
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = (ShowAppWindow ? SW_SHOW : SW_HIDE);
ShExecInfo.hInstApp = NULL;
// Spawn the process
if (ShellExecuteEx(&ShExecInfo) == FALSE)
{
Result = -1; // Failed to execute process
} else if (WaitToFinish)
{
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
}
return Result;
}
#endif
De hecho, fui yo quien lo señaló después de mi investigación: P. Gracias por la respuesta detallada. Si el nombre del ejecutable también contiene la cadena "actualizar" también activará el UAC. –
Edité mi respuesta y puse su nombre en los créditos :-) Debo agradecerle por preguntar y darme el motivo para publicar este fragmento de código. Recuerdo que he gastado al menos 1-2 días cuando necesitaba este código porque no había una pregunta correspondiente en SO. –
Gracias que no era necesario :). Realmente aprecio que se haya tomado el tiempo de escribir esta respuesta detallada, a pesar de que la pregunta ya tenía una respuesta aceptada. –