2013-05-30 2 views
0

всем, я застрял в месте и хотел получить предложение по этому вопросу.Обращение с административным токеном UAC

Мое приложение состоит из 79 форм, где для многочисленных мест требуются привилегии администратора. Программа запускается при запуске Windows, поэтому не может использовать административный токен по умолчанию (asAdministator). Lazarus не может создавать DLL ActiveX, поэтому другие варианты в мою пользу, я почти полностью выполнил большую часть моего проекта в лазаре, поэтому пути назад нет.

+0

Вы не можете обойти приглашение UAC, и это по дизайну. Обычный подход заключается в добавлении манифеста приложения в приложение, чтобы приглашение UAC отображалось только один раз, когда вы запускаете приложение. Таким образом, ваше приложение будет запускаться как администратор, и больше не будет запросов UAC. (Отдельный вопрос: что делает ваше приложение для того, чтобы оно требовало привилегий администратора?) –

+0

моя программа запускается при запуске Windows и при добавлении манифеста запускает программу nevers. – Rahul

+0

Затем я рекомендую не делать что-то в своем приложении, которое требует административных привилегий. Вы не можете обойти приглашение UAC, и это по дизайну. –

ответ

1

Если ваше приложение действительно действительно делает некоторые вещи, которые требуют доступа администратора

и это действительно большой, если; почти никто не нуждается в этом

Допустим, вы хотите, чтобы начал услугу. Вы можете создать кнопку с щитом UAC на нем:

ss

Тогда в случае щелчка запуск повышенной копии себя, передавая параметр строки /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; 

Примечание: Любой код выпущен в общественное достояние. Никакой атрибуции не требуется.

Смежные вопросы