windows 如何在运行时向用户询问提升的权限?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6108851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 16:54:54  来源:igfitidea点击:

How can I ask the user for elevated permissions at runtime?

c++windowsqt

提问by Tamás Szelei

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?

我怎样才能复制这种行为?

采纳答案by Fivos Vilanakis

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.

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

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

假设您的主要应用程序是 App1.exe,然后您调用需要提升权限的辅助进程 App2.exe。



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:

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

<?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

B、可以在App1.exe中使用如下代码启动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:

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

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:

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

回答by larsmoa

See this question on elevating privileges only when required in C#and this article on User Account Control

请参阅有关仅在 C# 中需要时提升权限的问题有关用户帐户控制的文章

To sum it up: one needs to launch a new process with elevated permissions. The elevation level cannot be changed at runtime. Launching with elevated permissions is done either via WinAPI or embedding a correct manifest in the executable.

总结一下:需要启动一个具有提升权限的新进程。在运行时无法更改高程级别。以提升的权限启动是通过 WinAPI 或在可执行文件中嵌入正确的清单来完成的。

回答by Chris Becke

In a nutshell: Create two executable files for windows. The regular executable, and a worker exe file that you use to perform "elevated" operations (by passing command line options).

简而言之:为 Windows 创建两个可执行文件。常规可执行文件和用于执行“提升”操作(通过传递命令行选项)的工作 exe 文件。

To the second EXE file you add an application manifest file with a <requestExecutionLevel level="requireAdministrator"/>node.

向第二个 EXE 文件添加一个带有<requestExecutionLevel level="requireAdministrator"/>节点的应用程序清单文件。

When launching the worker app, make sure to use the QT function that wraps ShellExecute, NOT CreateProcess as CreateProcess simply fails to launch requireAdministrator apps, whereas ShellExecute (Being a shell function) can perform the UAC elevation prompt.

启动工作应用程序时,请确保使用封装 ShellExecute 的 QT 函数,而不是 CreateProcess,因为 CreateProcess 无法启动 requireAdministrator 应用程序,而 ShellExecute(作为外壳函数)可以执行 UAC 提升提示。

It is also possible to do this with ActiveX controls, but as you are targeting Qt that seems less appropriate.

也可以使用 ActiveX 控件执行此操作,但由于您的目标是 Qt,这似乎不太合适。

回答by J?rgen Sigvardsson

You can also launch a COM object in an elevated mode. See this MSDN articlefor more information.

您还可以在提升模式下启动 COM 对象。有关详细信息,请参阅此MSDN 文章