Если ваше приложение действительно действительно делает некоторые вещи, которые требуют доступа администратора
и это действительно большой, если; почти никто не нуждается в этом
Допустим, вы хотите, чтобы начал услугу. Вы можете создать кнопку с щитом UAC на нем:
Тогда в случае щелчка запуск повышенной копии себя, передавая параметр строки /StartService
команду:
procedure TForm1.StartService(Sender: TObject);
begin
if IsUserAnAdmin then
begin
//no need to elevate, we're already an admin
StartService();
Exit;
end;
//We're a standard user, relaunch elevated to start the service
RunAsAdmin(0, ParamStr(0), '/StartService');
end;
с помощником чтобы проверить, есть ли у нас административные привилегии:
///This function tells us if we're running with administrative permissions.
function IsUserAdmin: Boolean;
var
b: BOOL;
AdministratorsGroup: PSID;
begin
{
This function returns true if you are currently running with admin privelages.
In Vista and later, if you are non-elevated, this function will return false (you are not running with administrative privelages).
If you *are* running elevated, then IsUserAdmin will return true, as you are running with admin privelages.
}
b := AllocateAndInitializeSid(
SECURITY_NT_AUTHORITY,
2, //2 sub-authorities
SECURITY_BUILTIN_DOMAIN_RID, //sub-authority 0
DOMAIN_ALIAS_RID_ADMINS, //sub-authority 1
0, 0, 0, 0, 0, 0, //sub-authorities 2-7 not passed
AdministratorsGroup);
if (b) then
begin
if not CheckTokenMembership(0, AdministratorsGroup, b) then
b := False;
FreeSid(AdministratorsGroup);
end;
Result := b;
end;
Уловка для запуска приложения в качестве администратора r следует использовать ShellExecute с runas глагол. я когда-либо создал удобную обертку:
function RunAsAdmin(hWnd: HWND; filename: string; Parameters: string): Boolean;
{
See Step 3: Redesign for UAC Compatibility (UAC)
http://msdn.microsoft.com/en-us/library/bb756922.aspx
}
var
sei: TShellExecuteInfo;
begin
ZeroMemory(@sei, SizeOf(sei));
sei.cbSize := SizeOf(TShellExecuteInfo);
sei.Wnd := hwnd;
sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
sei.lpVerb := PChar('runas');
sei.lpFile := PChar(Filename); // PAnsiChar;
if parameters <> '' then
sei.lpParameters := PChar(parameters); // PAnsiChar;
sei.nShow := SW_SHOWNORMAL; //Integer;
Result := ShellExecuteEx(@sei);
end;
Теперь вам просто нужно следить за переключателем /StartService
командной строки при запуске приложения. В этом быстром и грязном коде я помещаю его в FormActivate. На самом деле вы должны поместить его в файл проекта до Application.Run:
procedure TForm1.FormActivate(Sender: TObject);
begin
if FindCmdLineSwitch('startService', True) then
begin
//If we're not an admin, then use ShellExecute to launch ourselves as one
if not IsUserAdmin then
begin
//Relaunch ourselves as an admin
Toolkit.RunAsAdmin(0, ParamStr(0), '/StartService'); //don't forget to pass the command option
Application.Terminate;
Exit;
end;
//We are an admin; do the updates.
StartOurService();
MessageDlg('Service started!', mtInformation, [mbOk], 0);
Application.Terminate;
Exit;
end;
end;
Примечание: Любой код выпущен в общественное достояние. Никакой атрибуции не требуется.
Вы не можете обойти приглашение UAC, и это по дизайну. Обычный подход заключается в добавлении манифеста приложения в приложение, чтобы приглашение UAC отображалось только один раз, когда вы запускаете приложение. Таким образом, ваше приложение будет запускаться как администратор, и больше не будет запросов UAC. (Отдельный вопрос: что делает ваше приложение для того, чтобы оно требовало привилегий администратора?) –
моя программа запускается при запуске Windows и при добавлении манифеста запускает программу nevers. – Rahul
Затем я рекомендую не делать что-то в своем приложении, которое требует административных привилегий. Вы не можете обойти приглашение UAC, и это по дизайну. –