为 EXE 清单文件进行自定义
当你为 Windows 目标平台构建一个项目时,RAD Studio 会自动包含一个应用程序清单文件。你可以使用默认的 应用程序清单文件 作为你的自定义应用程序清单文件的基础:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
创建自定义应用程序清单文件
为了实现这一点,你需要一个 资源编辑/检查器 程序来修改 EXE 文件的清单。我个人使用 Angus Johnson’s Software,因为它简单易用。
修改所需的提升级别
默认的应用程序清单声明所需的提升级别为 asInvoker
,这意味着你的应用程序将与其父进程具有相同的提升级别。如果你想将应用程序提升到 Windows 管理员特权级别,只需在 requestedExecutionLevel
标签中将 level
属性的值从 asInvoker
修改为 requireAdministrator
:
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
-
uiAccess
-
false — 应用程序不需要驱动桌面上其他窗口的 UI。非提供可访问性的应用程序应该将此标志设置为 false。需要驱动其他窗口的应用程序(例如屏幕键盘)应该将此值设置为 true。
-
true — 应用程序被允许绕过 UI 保护级别来驱动桌面上更高特权窗口的输入。这种设置仅应用于 UI 可访问性应用程序。
-
-
Level : 这里有一个表格解释了在应用程序清单中声明的 Level 和其 行为。
注意: 用户仍需要管理员权限或凭据才能以管理员特权级别运行应用程序。
你可以在 Microsoft Docs 网站上找到更多信息:/MANIFESTUAC (将 UAC 信息嵌入清单)
修改 DPI 感知
为了创建一个 DPI 感知的应用程序,你需要在应用程序清单中声明 DPI 感知。例如,要声明应用程序为每个监视器的 DPI 感知,请在 </assembly>
标签之前添加以下内容:
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
测试管理权限
以下 C++ 代码片段可以用来快速测试你的应用程序是否需要(并且正确获得)管理特权级别。通过将应用程序的所需提升级别声明为 requireAdministrator
,然后执行以下过程:
C++:
#include <System.Win.Registry.hpp>
#include <Winapi.Windows.hpp>
void __fastcall isAdmin(TObject *Sender){
TRegistry *reg;
bool openResult;
reg = new TRegistry(KEY_READ);
reg->RootKey = HKEY_LOCAL_MACHINE;
reg->Access = KEY_WRITE;
openResult = reg->OpenKey("Software\\MyCompanyName\\MyApplication\\" , true);
if (openResult != true){
MessageDlg("无法写入注册表。你的应用程序不具有管理员级别的权限。",
TMsgDlgType::mtError, mbOKCancel, 0);
}else{
MessageDlg("允许写入注册表。你的应用程序具有管理员级别的权限。",
TMsgDlgType::mtInformation, mbOKCancel, 0);
}
reg->CloseKey();
reg->Free;
}
-
应用程序会显示以下其中一条消息:
-
无法写入注册表。你的应用程序不具有管理员级别的权限。
-
允许写入注册表。你的应用程序具有管理员级别的权限。
-
这种测试之所以有效,是因为你需要管理员级别的权限才能写入 HKEY_LOCAL_MACHINE\Software
部分的注册表。代码片段并没有实际写入注册表,只是请求写入权限。
请确保你在构建应用程序后,在 IDE 之外执行它,因为 IDE 会使用管理员级别的权限调试应用程序(不尊重你的应用程序清单)。
© 2021 - Sofiane Hamlaooui - 使世界变得更好 🌎
讨论
发表评论
访客评论在网站上显示前将被审核。
还没有评论。成为第一个开始讨论的人!