如何在运行时请求用户提升的权限? [英] How can I ask the user for elevated permissions at runtime?

查看:154
本文介绍了如何在运行时请求用户提升的权限?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

某些应用程序从常规用户开始,在必要时会要求提升权限(例如,文件管理器需要写入此类文件夹),然后继续操作。



如何复制此行为?

解决方案

Tamás指出,您需要启动一个具有更高权限的新流程。我在过去搜索了很多,但我没有找到任何办法提升当前过程的权利。



我们说你的主要应用程序是App1.exe然后你调用辅助进程App2.exe,这需要提高权限。






A。你可以在你的App2.exe中嵌入一个清单,但是更简单的方法是创建一个名为App2.exe.manifest的清单文件,并将其放在与App2.exe相同的目录中。
注意:!奇怪的是,如果您的应用程序的名称不是App2.exe而是App2_install.exe或App2_setup.exe(即如果应用程序名称包含安装或设置),UAC对话框将自动出现在Windows Vista / Windows 7并会要求提升的权利,即使没有清单文件!
这是清单文件的示例:

 <?xml version =1.0encoding =UTF -8standalone =yes?> 
< assembly xmlns =urn:schemas-microsoft-com:asm.v1manifestVersion =1.0>
< trustInfo xmlns =urn:schemas-microsoft-com:asm.v3>
< security>
< requestedPrivileges>
< requestedExecutionLevel level =requireAdministratoruiAccess =false/>
< / requestedPrivileges>
< / security>
< / trustInfo>
< / assembly>






您可以在App1.exe中使用如下代码启动App2.exe

  QString AppToExec = qApp - > applicationDirPath()+/App2.exe; 
//将App2.exe的所有必需参数放入AppParams string
QString AppParams =;
if(0!= genWin32ShellExecute(AppToExec,
,//默认动词:open或exec
AppParams,
false, $ b true))//等待完成
{
//(...)句柄错误
}

...最后,这是Win32函数的代码genWin32ShellExecute()我在Win32 O / S上使用QT时创建了启动进程或打开文档: / p>

标题:

  #ifdef Q_OS_WIN //实现genWin32ShellExecute()特别是对于UAC 
#includeqt_windows.h
#includeqwindowdefs_win.h
#include< shellapi.h>

int genWin32ShellExecute(QString AppFullPath,
QString Verb,
QString Params,
bool ShowAppWindow,
bool WaitToFinish);
#endif

CPP:
$ b

  //使用给定的命令执行/打开指定的应用程序/文档
//行参数
//(如果WaitToFinish = = true,等待spawn进程完成)
//
//动词参数值:
//相关联的AppFullPath的退动动词
//edit 启动编辑器并打开文档进行编辑。
//find从指定的目录开始搜索。
//open启动应用程序。如果此文件不是可执行文件,则会启动其关联的应用程序。
//print打印文档文件。
//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;

//设置所需的结构
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;

//生成进程
if(ShellExecuteEx(& ShExecInfo)== FALSE)
{
Result = -1; //无法执行进程
} else if(WaitToFinish)
{
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
}

return Result;
}
#endif


Some applications, started with a regular user will ask for elevated permissions when necessary (e.g. a file manager needs to write such folder), and then carry on with the operation.

How can I replicate this behavior?

解决方案

As Tamás pointed out you need to launch a new process with elevated rights. I searched a lot in the past but I did not find any way to elevate the rights of the current process.

Lets say your primary app is App1.exe and then you call a secondary process App2.exe which requires elevated rights.


A. You can embed a manifest in your App2.exe but the simpler way is to create a manifest file [a text file] named App2.exe.manifest with the following contents and put it in the same directory as App2.exe. Note: !! Strangely enough, if the name of your application is not App2.exe but App2_install.exe or App2_setup.exe (i.e. if the application name contains the "install" or "setup") an UAC Dialog will appear automatically in Windows Vista / Windows 7 and will ask for elevated rights even there is no manifest file !! This is a sample of the manifest file:

<?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. You can use a code like the following in App1.exe to launch the 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
}

...and finally, this is the code of the Win32 function genWin32ShellExecute() I created to launch a process or open a document when using QT on a 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

这篇关于如何在运行时请求用户提升的权限?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆