You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi开发Windows服务:如何以指定管理员权限运行交互会话EXE

可行性分析与实现方案

完全可行。要实现在已登录用户的交互会话中以指定管理员身份启动高权限EXE,需要解决三个核心问题:令牌的会话关联、高权限令牌的获取、正确的进程创建上下文设置。你的两个现有函数分别存在以下问题:

  • RunApp:通过WTSQueryUserToken获取的是当前登录用户的普通权限令牌,没有管理员elevated权限,所以启动的程序权限不足。
  • RunAppAsUser:LogonUser创建的令牌属于新的非交互会话(默认会话0,而用户交互会话通常是1及以上),即使指定了桌面路径,也无法关联到用户的活跃会话,导致程序在后台运行不可见,甚至启动失败。

正确实现步骤与代码

以下是完整的Delphi实现代码,包含令牌复制、会话绑定、权限提升的关键逻辑:

uses
  Windows, SysUtils, WinSvc, Wtsapi32;

// 额外需要的API声明
function DuplicateTokenEx(hExistingToken: THandle; dwDesiredAccess: DWORD;
  lpTokenAttributes: PSecurityAttributes; ImpersonationLevel: SECURITY_IMPERSONATION_LEVEL;
  TokenType: TOKEN_TYPE; var phNewToken: THandle): BOOL; stdcall; external 'advapi32.dll';

function SetTokenInformation(hToken: THandle; TokenInformationClass: TOKEN_INFORMATION_CLASS;
  TokenInformation: Pointer; TokenInformationLength: DWORD): BOOL; stdcall; external 'advapi32.dll';

function CreateEnvironmentBlock(var lpEnvironment: Pointer; hToken: THandle; bInherit: BOOL): BOOL; stdcall; external 'userenv.dll';

function DestroyEnvironmentBlock(lpEnvironment: Pointer): BOOL; stdcall; external 'userenv.dll';

function RunAppAsAdminInUserSession(const Path, UserName, Password, Domain: string): Boolean;
var
  ActiveSessionId: DWORD;
  UserSessionToken, AdminToken, DuplicatedToken: THandle;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  EnvBlock: Pointer;
  SessionIdInfo: DWORD;
begin
  Result := False;
  if not FileExists(Path) then Exit;

  // 1. 获取当前活跃控制台会话ID
  ActiveSessionId := WTSGetActiveConsoleSessionID;
  if ActiveSessionId = $FFFFFFFF then Exit;

  // 2. 获取用户会话的令牌(用于后续绑定会话)
  if not WTSQueryUserToken(ActiveSessionId, UserSessionToken) then Exit;
  try
    // 3. 登录目标管理员账号,获取令牌
    if not LogonUser(PWideChar(UserName), PWideChar(Domain), PWideChar(Password),
      LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, AdminToken) then Exit;
    try
      // 4. 复制管理员令牌为Primary Token,用于创建进程
      if not DuplicateTokenEx(AdminToken, TOKEN_ALL_ACCESS, nil,
        SecurityIdentification, TokenPrimary, DuplicatedToken) then Exit;
      try
        // 5. 将复制后的令牌绑定到用户的活跃会话ID
        SessionIdInfo := ActiveSessionId;
        if not SetTokenInformation(DuplicatedToken, TokenSessionId,
          @SessionIdInfo, SizeOf(SessionIdInfo)) then Exit;

        // 6. 创建用户环境块,确保进程在用户会话的环境中运行
        if not CreateEnvironmentBlock(EnvBlock, DuplicatedToken, False) then Exit;
        try
          // 7. 设置进程启动信息
          ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
          StartupInfo.cb := SizeOf(StartupInfo);
          StartupInfo.lpDesktop := PChar('WinSta0\Default');
          StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
          StartupInfo.wShowWindow := SW_SHOWNORMAL;

          ZeroMemory(@ProcessInfo, SizeOf(ProcessInfo));

          // 8. 以管理员令牌创建进程,启用高权限标志
          Result := CreateProcessAsUserW(DuplicatedToken, nil, PChar(Path), nil, nil, False,
            CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT, EnvBlock, nil, StartupInfo, ProcessInfo);

          if Result then
          begin
            CloseHandle(ProcessInfo.hProcess);
            CloseHandle(ProcessInfo.hThread);
          end;
        finally
          DestroyEnvironmentBlock(EnvBlock);
        end;
      finally
        CloseHandle(DuplicatedToken);
      end;
    finally
      CloseHandle(AdminToken);
    end;
  finally
    CloseHandle(UserSessionToken);
  end;
end;

关键逻辑说明

  • 会话绑定:通过SetTokenInformation将管理员令牌的会话ID设置为用户的活跃会话ID,确保进程在用户的交互会话中启动,而非独立的系统会话。
  • 令牌复制:DuplicateTokenEx将LogonUser获取的模拟令牌转换为可用于创建进程的主令牌(Primary Token)。
  • 环境块创建:CreateEnvironmentBlock生成用户会话的环境变量,保证进程拥有正确的上下文(如桌面路径、系统变量等)。
  • 高权限保障:管理员账号本身具备elevated权限,只要令牌正确传递,启动的进程会自动继承该权限;若需要额外启用特定特权,可在复制令牌后调用AdjustTokenPrivileges添加对应权限。

注意事项

  1. 服务本身需要以Local System身份运行,才能获取WTSQueryUserToken的调用权限。
  2. 目标管理员账号必须具备允许本地登录和作为服务登录的权限(可在组策略中配置)。
  3. 若启动的EXE需要UAC提升,需确保其本身带有requestedExecutionLevel为requireAdministrator的manifest,或者在CreateProcessAsUser的标志中添加CREATE_ELEVATED_PROCESS(仅Windows Vista及以上支持)。

内容的提问来源于stack exchange,提问作者Cristian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:24:53