Run this program as an administrator (Or how to get the licence UAC Admin during the necessary moment) [closed]
It is the second attempt to receive the answer on a question. Very much I apologise, but my English very bad, therefore it is very difficult to me to explain that I want, especially in technical questions :_(
I try once again, this time with a concrete example, that it is necessary for me.
DelphiXe, Win7x64. Windows Uac is On. The user works with the rights of the Administrator.
The program (example) which should copy files from one place in another is given. She should be started by usual way (not on behalf of the Admin). Therefore gluing to a manifes(*.rc) EXE-file (which grants the rights of the Admin - requests at start more truly) is not required. Copying should be carried out by usual way - the rights of Admin should be requested only in case of need and without restart of the program.
Problem (in a code are marked "*"): 1. How to define that Windows UAC is present at system and whether it is Enabled 2. How to get the licence of Admin right (to deduce message Windows UAC) only in case of need and actually to get this licence for the program not restarting it
Example - file managers 'Far manager' (or 'Total Commander') can so to do - they copy files at usual start (not on behalf of the Admin), and cause inquiry UAC only when business concerns system folders. Thus programs are not restarted and at first give out the prevention.
P.S. It is grateful for the help and editing of my posts.
Program: Form, one button, opendialog, savedialog
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls开发者_JAVA技巧, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
OpenDialogFROM: TOpenDialog;
Button1: TButton;
SaveDialogTO: TSaveDialog;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Function TestPathWrite(path:string):bool;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Function IsWindowsUAC_Enabled:bool; // Test Windows UAC turn on (*)
begin
Result:=false;
// ????
// How to define, whether function UAC is included in system - enabled (we will admit, that we work in OS is more senior XP)
end;
Function TurnOnAdminRight:bool; // To activate the rights of the Administrator to operation (*)
begin
Result:=false;
// ????
// How to activate message Windows UAC (approximately "To allow to make to this program changes to the computer?" or something similar)
// and to get the licence of the Administrator for this program?
end;
Function TForm1.TestPathWrite(path:string):bool;
var f:file;Err:integer;
begin
Result:=false;assignfile(f,IncludeTrailingPathDelimiter(path)+'$$TestFile$$.tmp');
{$I-}
Rewrite(f);
{$I+}
Err:=IoResult;
If Err<>0 then begin
if Err=5 then begin // Access denided
if IsWindowsUAC_Enabled then // Windows UAC is ON
if TurnOnAdminRight=True then TestPathWrite(path); // Repeated check, else exit whith error message
end;
Showmessage('Error write to path: '+path+', Error: '+inttostr(Err));
Exit;
end;
CloseFile(f);Erase(f);Result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// Test procedure by which it can be demanded the rights of the Administrator
// It also could be record procedure in windows register or another by which the rights can be demanded, and can't be demanded
// The problem to request the rights (and to include) only when they are necessary
if OpenDialogFROM.Execute then if SaveDialogTO.Execute then
if FileExists(OpenDialogFROM.FileName)=true then
if TestPathWrite(ExtractfilePath(SaveDialogTO.FileName))=true then
if CopyFile(Pchar(OpenDialogFROM.FileName),Pchar(SaveDialogTO.FileName),true)=true then
Showmessage('File: '+OpenDialogFROM.FileName+' it is successfully copied as: '+SaveDialogTO.FileName);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SaveDialogTo.Options:=[ofNoTestFileCreate,ofEnableSizing,ofDontAddToRecent]; // SaveDialog does not do check on record
end;
end.
Copying will be normal for example at
From d:\MyTest.txt in e:\MyNew.txt
And the message with inquiry of rights UAC should to appear for example at
From d:\MyTest.txt in c:\Windows\MyNew.txt
I think you need to start another process with raised privileges (using a manifest...). Either this can be a separate EXE, or the same EXE (perhaps with some appropriate command-line argument).
Of course, to the end user, this will look like if the original process somehow 'magically' got raised privileges.
You can check if UAC is active using this function
interface
uses
Registry, SysUtils;
function IsUACActive: Boolean;
implementation
function IsUACActive: Boolean;
var
Reg: TRegistry;
begin
Result := FALSE;
// There's a chance it's active as we're on Vista or Windows 7. Now check the registry
if CheckWin32Version(6, 0) then
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System') then
begin
if (Reg.ValueExists('EnableLUA')) and (Reg.ReadBool('EnableLUA')) then
Result := TRUE;
end;
finally
FreeAndNil(Reg);
end;
end;
end;
You can run an elevated process using the following function:
...
interface
uses
Windows, ShellAPI, Forms;
type
TExecuteFileOption = (
eoHide,
eoWait,
eoElevate
);
TExecuteFileOptions = set of TExecuteFileOption;
function ExecuteFile(Handle: HWND; const Filename, Paramaters: String; Options: TExecuteFileOptions): Integer;
implementation
function ExecuteFile(Handle: HWND; const Filename, Paramaters: String; Options: TExecuteFileOptions): Integer;
var
ShellExecuteInfo: TShellExecuteInfo;
ExitCode: DWORD;
begin
Result := -1;
ZeroMemory(@ShellExecuteInfo, SizeOf(ShellExecuteInfo));
ShellExecuteInfo.cbSize := SizeOf(TShellExecuteInfo);
ShellExecuteInfo.Wnd := Handle;
ShellExecuteInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
if (eoElevate in Options) and (IsUACActive) then
ShellExecuteInfo.lpVerb := PChar('runas');
ShellExecuteInfo.lpFile := PChar(Filename);
if Paramaters <> '' then
ShellExecuteInfo.lpParameters := PChar(Paramaters);
// Show or hide the window
if eoHide in Options then
ShellExecuteInfo.nShow := SW_HIDE
else
ShellExecuteInfo.nShow := SW_SHOWNORMAL;
if ShellExecuteEx(@ShellExecuteInfo) then
Result := 0;
if (Result = 0) and (eoWait in Options) then
begin
GetExitCodeProcess(ShellExecuteInfo.hProcess, ExitCode);
while (ExitCode = STILL_ACTIVE) and
(not Application.Terminated) do
begin
sleep(50);
GetExitCodeProcess(ShellExecuteInfo.hProcess, ExitCode);
end;
Result := ExitCode;
end;
end;
To run an elevated, hidden process and wait for it to exit:
ExecuteFile(Self.Handle, 'Filename', 'Parameters', [eoHide, eoWait, eoElevate]);
Hope this helps
Once a process has started as at a user privilege level this process can't get admin privileges. This is necessary since the privilege level doubles as integrity level. So you need in some way start a new elevated process or communicate with an existing elevated process.
The question is difficult to understand... since there is no question.
From what you wrote, I guess that you want to perform some actions which requires the Administrator elavated rights.
It's not enough to run as Adminitrator, to be able to execute all actions.
The UAC expects to elevate the current user rights, even if he/she is a local administrator, to perform some security-related actions.
Read this technical article from Microsoft for step-by-step guidance about how the UAC works.
精彩评论