10
votes

Vous recherchez le code Delphi 7 pour détecter si un programme est démarré avec les droits de l'administrateur?

Je recherche travail ( manifestement ) Code Delphi 7 Je peux donc vérifier si mon programme est lancé avec les droits de l'administrateur .

Merci d'avance

[--- Mise à jour importante ---]

Après avoir examiné le code dans les réponses jusqu'à présent, je me rends compte que ma question n'est peut-être pas si claire, ou du moins n'est pas complète:

  • Je veux savoir si mon programme Delphi 7 est démarré avec la case à cocher "Exécuter en tant qu'administrateur". / forte>.

  • En d'autres termes: Je veux savoir s'il est possible de savoir mon Delphi 7 Programme de créer / mettre à jour des fichiers dans les fichiers C: \ Programme ... Dossiers < / fort>.

    Vérification juste si vous avez des droits d'administrateur ne suffisent pas pour cela.


3 commentaires

Le moyen accepté de le faire est de manifester avec Exiger admin tout programme qui doit écrire dans le répertoire des fichiers de programme.


Autant que je sache, les droits de l'administrateur suffisent pour créer / mettre à jour des fichiers dans C: \ Program Files!


@Andreas: non pas, vous devez avoir démarré votre programme avec l'option "Exécuter en tant qu'administrateur". J'ai des droits d'administrateur complet sur mon PC de développement, mais je ne peux pas créer / mettre à jour un fichier dans c: \ Program Files ... Sauf si je ne le démarre avec "Exécuter ad admin". Étant donné que le même programme (un programme de mise à jour Web par la manière) peut être exécuté avec ou sans «exécuter comme administrateur», je devrais pouvoir vérifier cet état.


7 Réponses :


6
votes

Project Jedi's bibliothèque de code Jedi a une fonction isadministrator dans l'unité JCLSecurity qui vous dira . Cela fonctionne toujours dans Delphi 7.


0 commentaires

1
votes

Ce code fonctionne sous 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;


2 commentaires

Ce code vérifie si vous êtes membre du groupe Administrateurs. Le problème avec ce code est que vous pouvez être membre du groupe Administrateurs, mais vous n'avez aucun droit administratif. De même, vous pouvez avoir des droits d'administrateur, mais ne pas être membre du groupe Administrateurs. Cette fonction pourrait mieux être appelée ismemberofadministratorsgroup , avec la compréhension duquel faire partie du groupe de l'administrateur ne signifie pas que vous avez les droits d'un administrateur.


-1, cette fonction est immédiatement collées par différents PPL et, comme Ian Boyd, a déjà déclaré seulement vérifier si l'un est membre du groupe de l'administrateur.



15
votes

L'API Windows (utilisé) pour avoir une fonction d'assistance ( ISUSERANADMIN ) Pour dire si vous utilisez des privilèges administratifs.

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;


0 commentaires

10
votes
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.

0 commentaires

3
votes

La manière recommandée par Microsoft de résoudre ce problème: diviser l'application en deux.

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

La première application vérifie s'il est nécessaire d'exécuter le second.

La deuxième application contient un manifeste "exige admin" (comme David écrit) et que vous l'ouvrez avec le verbe de ShellexecuteEx 'Runas'.

En cas de mise à jour du Web, le flux de travail pourrait être comme celui-ci:

updater1.exe

  1. vérifie s'il existe des mises à jour disponibles.
  2. demande éventuellement à l'utilisateur s'il souhaite installer les mises à jour.
  3. Télécharge les mises à jour d'un emplacement temporaire.
  4. Runs Updater2.exe avec ShellexecuteEx et le verbe 'Runas'.

    updater2.exe

    1. sera évalué sur UAC si les utilisateurs confirment l'invite ou ne seront pas du tout exécutés.
    2. peut alors copier les fichiers de l'emplacement Temp vers l'emplacement final.

      Cela présente plusieurs avantages:

      • Le programme de mise à jour2 ne contient que les opérations minimales à exécuter élevées.
      • La mise à jour2 peut faire partie des fichiers téléchargés.
      • Il n'est pas nécessaire de vérifier aucun privilège, l'UAC prend en charge cela.

        Cela fonctionne également sur Windows XP, vous vous présenterez avec une boîte de dialogue Connexion si vous n'êtes pas un administrateur.


0 commentaires

2
votes

jwscl (la bibliothèque de Security Jedi Windows) a une fonction pour cela: JwcheckadministratorAccess .

Uses
  JwsclToken;

IsElevated := JwCheckAdministratorAccess;


1 commentaires

Désolé de répondre à la vieille question, je ne sais pas comment je suis arrivé ici mais je n'ai pas remarqué



2
votes

J'ai testé ce code avec Delphi 7, sous Windows XP, 7 et 8 (administrateur et comptes limités): xxx


0 commentaires