Ищете код Delphi 7 для определения, запущена ли программа с правами администратора?

Я ищу работающий (очевидно) код Delphi 7, чтобы проверить, моя программа запущена с правами администратора >.

заранее спасибо

[--- ВАЖНОЕ ОБНОВЛЕНИЕ ---]

Изучив код в ответах до сих пор, я понимаю, что мой вопрос, возможно, не так ясен или, по крайней мере, не завершен:

  • Я хочу знать, запускается ли моя программа Delphi 7 с установленным флажком "Запуск от имени администратора".

  • Другими словами: я хочу знать, может ли моя программа Delphi 7 создавать/обновлять файлы в папках c:\Program Files....

Для этого недостаточно просто проверить, есть ли у вас права администратора.


person Edelcom    schedule 07.06.2011    source источник
comment
Общепринятый способ сделать это — указать с помощью require admin любую программу, которой необходимо записать в каталог программных файлов.   -  person David Heffernan    schedule 20.06.2011
comment
Насколько я знаю, прав администратора ДОСТАТОЧНО для создания/обновления файлов в c:\program files!   -  person Andreas    schedule 30.06.2011
comment
@Andreas: это не так, вы должны запустить свою программу с опцией «Запуск от имени администратора». У меня есть полные права администратора на моем компьютере для разработки, но я не могу создать/обновить файл в c:\program files... если только я не запущу его с помощью «Run ad admin». Поскольку одна и та же программа (кстати, программа веб-обновления) может быть запущена с параметром «Запуск от имени администратора» или без него, я должен иметь возможность проверить это состояние.   -  person Edelcom    schedule 30.06.2011


Ответы (6)


Windows API (используется) для вспомогательной функции (IsUserAnAdmin), чтобы узнать, работаете ли вы с правами администратора.

OS              Account Type   UAC           IsUserAdmin
==============  =============  ============  ===========
Windows XP      Standard       n/a           False
Windows XP      Administrator  n/a           True
Windows Vista   Standard       Disabled      False
Windows Vista   Administrator  Disabled      True
Windows Vista   Standard       Not Elevated  False
Windows Vista   Administrator  Not Elevated  False
Windows Vista   Standard       Elevated      True
Windows Vista   Administrator  Elevated      True

Функция оболочки Shell32 устарела; что хорошо, потому что это была просто оболочка вокруг другого кода, который вы все еще можете вызывать себя:

function IsUserAdmin: Boolean;
var
  b: BOOL;
  AdministratorsGroup: PSID;
begin
  {
    This function returns true if you are currently running with admin privileges.
    In Vista and later, if you are non-elevated, this function will return false 
    (you are not running with administrative privileges).
    If you *are* running elevated, then IsUserAdmin will return true, as you are 
    running with admin privileges.

    Windows provides this similar function in Shell32.IsUserAnAdmin. 
    But the function is deprecated, and this code is lifted
    from the docs for CheckTokenMembership:
      http://msdn.microsoft.com/en-us/library/aa376389.aspx
  }

  {
    Routine Description: This routine returns TRUE if the callers
    process is a member of the Administrators local group. Caller is NOT
    expected to be impersonating anyone and is expected to be able to
    open its own process and process token.
      Arguments: None.
      Return Value:
        TRUE - Caller has Administrators local group.
        FALSE - Caller does not have Administrators local group.
  }
  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;

Другими словами: Эта функция дает вам ответ, который вы хотите: Может ли пользователь обновлять Program Files.

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

person Ian Boyd    schedule 12.06.2011

Библиотека кодов JEDI проекта JEDI имеет функцию IsAdministrator в модуле JclSecurity, которая сообщит вам об этом. Он все еще работает в Delphi 7.

person Ken White    schedule 07.06.2011

Рекомендуемый Microsoft способ решения этой проблемы: разделить приложение на две части.

http://msdn.microsoft.com/en-us/library/aa511445.aspx

Первое приложение проверяет, нужно ли запускать второе.

Второе приложение содержит манифест «требуется администратор» (как написал Дэвид), и вы открываете его с помощью глагола «runas» ShellExecuteEx.

В случае веб-обновления рабочий процесс может быть таким:

Updater1.exe

  1. Проверяет наличие доступных обновлений.
  2. Опционально спрашивает пользователя, хочет ли он установить обновления.
  3. Загружает обновления во временное расположение.
  4. Запускает Updater2.exe с ShellExecuteEx и глаголом runas.

Updater2.exe

  1. Будет проверено в UAC, если пользователи подтвердят приглашение или вообще не будут запущены.
  2. Затем можно скопировать файлы из временного местоположения в конечное местоположение.

Это имеет несколько преимуществ:

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

Это также работает в Windows XP, вам будет представлен диалог входа в систему, если вы не являетесь администратором.

person Jens Mühlenhoff    schedule 17.08.2011

В Jwscl (библиотеке безопасности Windows для джедаев) есть функция для этого: .

function JwCheckAdministratorAccess: boolean;

использование очень простое:

Uses
  JwsclToken;

IsElevated := JwCheckAdministratorAccess;

Эта функция также работает в Windows Vista и более поздних версиях, если включен UAC. Если текущий процесс не повышен, возвращаемое значение равно false, даже если токен содержит группу администраторов (которая тогда отключена). Эта функция определяет членство в группе администраторов, что означает, что пользователю не обязательно быть непосредственно в группе администраторов, вместо этого группа может быть членом группы администраторов.

person Remko    schedule 01.12.2011
comment
Извините за ответ на старый вопрос, не знаю, как я сюда попал, но не заметил - person Remko; 01.12.2011

Я тестировал этот код с Delphi 7, в Windows XP, 7 и 8 (учетные записи администратора и ограниченные):

Function CheckTokenMembership(TokenHandle: THandle; SIdToCheck: PSID; var IsMember: Boolean): Boolean; StdCall; External AdvApi32;

Function IsAdmin: Boolean;
const
  DOMAIN_ALIAS_RID_ADMINS = $00000220;
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
var
  Admin: Boolean;
  AdmGroup: PSID;
Begin
  Admin := AllocateAndInitializeSid(SECURITY_NT_AUTHORITY,
    2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
    0, 0, 0, 0, 0, 0, AdmGroup);
  If (Admin) Then
  Begin
    If (not CheckTokenMembership(0, AdmGroup, Admin)) Then
      Admin := False;
    FreeSid(AdmGroup);
  end;
  Result := Admin;
end;
person Guybrush    schedule 20.04.2014

Этот код работает под D7..XE inc.

function IsWindowsAdministrator: Boolean;
// Returns TRUE if the user has administrator priveleges
// Returns a boolean indicating whether or not user has admin
// privileges. Call only when running under NT. Win9.x will return false!
var
  hAccessToken       : tHandle;
  ptgGroups          : pTokenGroups;
  dwInfoBufferSize   : DWORD;
  psidAdministrators : PSID;
  int                : integer;            // counter
  blnResult          : boolean;            // return flag

const
  SECURITY_NT_AUTHORITY: SID_IDENTIFIER_AUTHORITY =
    (Value: (0,0,0,0,0,5)); // ntifs
  SECURITY_BUILTIN_DOMAIN_RID: DWORD = $00000020;
  DOMAIN_ALIAS_RID_ADMINS: DWORD = $00000220;
  DOMAIN_ALIAS_RID_USERS : DWORD = $00000221;
  DOMAIN_ALIAS_RID_GUESTS: DWORD = $00000222;
  DOMAIN_ALIAS_RID_POWER_: DWORD = $00000223;

begin
  Result := False;
  blnResult := OpenThreadToken( GetCurrentThread, TOKEN_QUERY,
                                True, hAccessToken );
  if ( not blnResult ) then
  begin
    if GetLastError = ERROR_NO_TOKEN then
    blnResult := OpenProcessToken( GetCurrentProcess,
                       TOKEN_QUERY, hAccessToken );
  end;

  ptgGroups := nil;

  if ( blnResult ) then
  try

    GetMem(ptgGroups, 1024);
    blnResult := GetTokenInformation( hAccessToken, TokenGroups,
                                      ptgGroups, 1024,
                                      dwInfoBufferSize );
    CloseHandle( hAccessToken );

    if ( blnResult ) then
    begin

      AllocateAndInitializeSid( SECURITY_NT_AUTHORITY, 2,
                                SECURITY_BUILTIN_DOMAIN_RID,
                                DOMAIN_ALIAS_RID_ADMINS,
                    0, 0, 0, 0, 0, 0,
                    psidAdministrators );
      {$IFOPT R+}
        {$DEFINE RMINUS}
        {$R-}
      {$ENDIF}
      for int := 0 to ptgGroups.GroupCount - 1 do

        if EqualSid( psidAdministrators,
                     ptgGroups.Groups[ int ].Sid ) then
        begin
          Result := True;
          Break;
        end;
      {$IFDEF IMINUS}
        {$R-}
        {$UNDEF IMINUS}
      {$ENDIF}

      FreeSid( psidAdministrators );
    end;

  finally
    If ptgGroups <> nil then
      FreeMem( ptgGroups );
  end;
end;
person Brian Frost    schedule 08.06.2011
comment
Этот код проверяет, являетесь ли вы членом группы администраторов. Проблема с этим кодом в том, что вы можете быть членом группы администраторов, но не иметь прав администратора. Точно так же вы можете иметь права администратора, но не быть членом группы администраторов. Эту функцию лучше было бы назвать IsMemberOfAdministratorsGroup, при том понимании, что членство в группе администратора не означает, что у вас есть права администратора. - person Ian Boyd; 12.06.2011
comment
-1, эта функция снова и снова вставляется разными людьми, и, как уже сказал Ян Бойд, проверяйте только, является ли он членом группы администратора. - person Remko; 01.12.2011