Delphi程序默认提权处理(以管理员权限运行软件)

从Vista以后的Window操作系统加入了UAC安全机制,一些特定的操作需要以管理员权限运行软件后才能够跑起来 (如: 修改注册表等操作)

若Delphi开发的软件涉及到一些操作需要使用到管理员权限,可以对项目进行相关配置,为程序提权; 

01. 配置一个提权的配置文件: XXX.manifest       

1 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
2 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
3 <security>
4 <requestedPrivileges>
5 <requestedExecutionLevel level="requireAdministrator"/>
6 </requestedPrivileges>
7 </security>
8 </trustInfo>
9 </assembly>

 

02. 在工程上右键 --> Options 对话框 进行配置

    

 

 

03. 注意一点: 此时Debug是不行的,会提示异常
     

 

    需要先编译程序,再运行编译后的程序,此时程序是提权了的,可以直接设置注册表;

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

若电脑为多人使用,特别是小孩子使用时,可以对电脑进行一些管控,

提供一个媒介软件,用以给特定的软件进行管理员权限授权,通过媒介软件运行的程序,拥有管理员权限,直接运行时,将没有相应的管理员权限;

01. 定义授权调用结构

type
  _STARTUPINFOW = record
    cb: DWORD;
    lpReserved: LPWSTR;
    lpDesktop: LPWSTR;
    lpTitle: LPWSTR;
    dwX: DWORD;
    dwY: DWORD;
    dwXSize: DWORD;
    dwYSize: DWORD;
    dwXCountChars: DWORD;
    dwYCountChars: DWORD;
    dwFillAttribute: DWORD;
    dwFlags: DWORD;
    wShowWindow: Word;
    cbReserved2: Word;
    lpReserved2: PByte;
    hStdInput: THandle;
    hStdOutput: THandle;
    hStdError: THandle;
  end;

  STARTUPINFOW = _STARTUPINFOW;

 

 02. 函数引用

function CreateProcessWithLogonW(lpUserName, lpDomain, lpPassword: LPCWSTR; //
  dwLogonFlags: DWORD; lpApplicationName: LPCWSTR; lpCommandLine: LPWSTR; //
  dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: LPCWSTR; //
  const lpStartupInfo: STARTUPINFOW; var lpProcessInformation: PROCESS_INFORMATION): BOOL; stdcall; external advapi32 name 'CreateProcessWithLogonW';

 

03. 授权调用

procedure TForm1.FormCreate(Sender: TObject);    
var
  STARTUPINFO: StartupInfoW;
  ProcessInfo: TProcessInformation;
  AUser, ADomain, APass, AExe: WideString;
const
  LOGON_WITH_PROFILE = $00000001;
  LOGON_NETCREDENTIALS_ONLY = $00000002;
begin
  FillChar(STARTUPINFO, SizeOf(StartupInfoW), 0);
  STARTUPINFO.cb := SizeOf(StartupInfoW);
  STARTUPINFO.dwFlags := STARTF_USESHOWWINDOW;
  STARTUPINFO.wShowWindow := SW_SHOW;
  AUser := 'administrator';  //Windows管理员账号
  APass := '123456';         //管理员密码
  ADomain := '';

  AExe := 'Project2.exe';  //要运行的软件
  if not CreateProcessWithLogonW(PWideChar(AUser), PWideChar(ADomain), PWideChar(APass), //
    LOGON_WITH_PROFILE, nil, PWideChar(AExe), //
    NORMAL_PRIORITY_CLASS, nil, nil, STARTUPINFO, ProcessInfo) then
    RaiseLastOSError;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  close;
end;

 上例中,虽然写入了账号和密码,但可以调整为弹窗输入账号密码的模式来进行处理,

 ---------------------------------------------------------------------------------------------------------------------------------------------------------

 第三种处理方式为使用 RunAs 进行解决;同样可以使程序拥有管理员权限;

 1 function RunAsAdmin(const Path, Params: string): Boolean;
 2 var
 3   sei: TShellExecuteInfo;
 4 begin
 5   FillChar(sei, SizeOf(sei), 0);
 6   sei.Wnd := 0;
 7   sei.cbSize := SizeOf(sei);
 8   sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
 9   sei.lpVerb := 'runas';
10   sei.lpFile := PChar(ExtractFileName(Path));
11   sei.lpDirectory := PChar(ExtractFilePath(Path));
12   sei.lpParameters := PChar(Params);
13   sei.nShow := SW_SHOWNORMAL;
14   Result := ShellExecuteEx(@sei);
15 end;

 

 调用方式:

RunAsAdmin('Daemon.exe', tmpP);

 

posted @ 2021-10-08 15:24  耗喜天涯  阅读(717)  评论(0编辑  收藏  举报