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);