Ищете код Delphi 7, чтобы определить, запускается ли программа с правами администратора? - PullRequest
8 голосов
/ 07 июня 2011

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

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

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

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

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

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

Недостаточно просто проверить, есть ли у вас права администратора.

Ответы [ 7 ]

15 голосов
/ 12 июня 2011

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;

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

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

6 голосов
/ 16 июня 2011
program Project1;

{$APPTYPE CONSOLE}

uses
  Windows,
  ShellAPI;

// high-level wrapper, see Ian Boyd's answer for details on this function
function IsUserAnAdmin(): BOOL; external shell32;

begin
  if IsUserAnAdmin() then
    Writeln('TEH R00T OMG')
  else
    Writeln('rtfmnoobkthx');

  Readln;
end.
5 голосов
/ 07 июня 2011

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

3 голосов
/ 17 августа 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, вы получаете диалоговое окно входа, если вы не являетесь администратором.

2 голосов
/ 20 апреля 2014

Я тестировал этот код с 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;
2 голосов
/ 01 декабря 2011

Jwscl (библиотека безопасности Windows Jedi) имеет функцию для этого: JwCheckAdministratorAccess .

function JwCheckAdministratorAccess: boolean;

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

Uses
  JwsclToken;

IsElevated := JwCheckAdministratorAccess;

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

1 голос
/ 08 июня 2011

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

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