2011-06-07 36 views
8

Busco trabajo (obviamente ) Delphi 7 Código por lo que se puede comprobar si mi programa se inicia con derechos de administrador.¿Busca el código Delphi 7 para detectar si un programa se inicia con derechos de administrador?

Gracias de antemano

[--- ACTUALIZACIÓN IMPORTANTE: ---]

Habiendo examinado el código en las respuestas hasta el momento, me di cuenta que mi pregunta tal vez no es tan claro, o por lo menos no es completa:

  • quiero saber si mi programa Delphi 7 se inicia con el cuadro 'Ejecutar como administrador' Verific.

  • En otras palabras: Quiero saber si es posible para mi programa Delphi 7 para crear archivos/actualización en el directorio C: \ Archivos de programa ... carpetas.

Solo basta con verificar si posee derechos de administrador para esto.

+0

La forma aceptada de hacer esto es manifestar con requieren admin cualquier programa que necesita para escribir al directorio de archivos de programa. –

+0

Por lo que sé, los derechos de administrador SON suficientes para crear/actualizar archivos en c: \ archivos de programa! – Andreas

+0

@Andreas: no es así, debe haber iniciado su programa con la opción 'Ejecutar como administrador'. Tengo todos los derechos de administrador en mi pc de desarrollo, pero no puedo crear/actualizar un archivo en c: \ archivos de programa ... a menos que lo inicie con 'Ejecutar administrador de anuncios'. Debido a que el mismo programa (un programa de actualización web por cierto) puede ejecutarse con o sin 'Ejecutar como administrador', debería poder verificar este estado. – Edelcom

Respuesta

5

El proyecto JEDI JEDI Code Library tiene una función IsAdministrator en la unidad JclSecurity que le dirá. Todavía funciona en Delphi 7.

1

Este código funciona en 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

Este código verifica si usted es miembro del grupo de administradores. El problema con este código es que puede ser miembro del grupo de administradores, pero no tener ningún derecho administrativo.Del mismo modo, puede tener derechos de administrador, pero no ser miembro del grupo de administradores. Esta función se podría llamar mejor 'IsMemberOfAdministratorsGroup', en el entendido de que formar parte del grupo de administradores no significa que usted tenga los derechos de un administrador. –

+0

-1, esta función es pegada una y otra vez por diferentes personas y, como ya dijo Ian Boyd, solo verifica si alguien es miembro del grupo del administrador. – Remko

15

La API de Windows (utilizado) para tener una función de ayuda (IsUserAnAdmin) para saber si se está ejecutando con privilegios administrativos.

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 

La función de envoltura Shell32 está obsoleta; lo cual está bien porque era a wrapper around other code, which you can still call mismo:

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; 

En otras palabras: Esta función le da la respuesta que desea: ¿Los archivos del programa de actualización del usuario.

Necesita estar cansado del código que verifica si es miembro del grupo del Administrador. Puede ser parte del grupo del Administrador, pero no tener privilegios administrativos. También puede tener privilegios administrativos, pero no ser parte del grupo del Administrador.

4
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. 
3

La forma recomendada por Microsoft para resolver este problema: divida la aplicación en dos.

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

los primeros controles de aplicaciones si es necesario ejecutar el segundo.

La segunda aplicación contiene un manifiesto "require admin" (como David escribió) y lo abre con el verbo ShellExecuteEx 'runas'.

En caso de un actualizador web del flujo de trabajo podría ser así:

Updater1.exe

  1. Comprueba si hay actualizaciones disponibles.
  2. Opcionalmente le pregunta al usuario si desea instalar las actualizaciones.
  3. Descarga las actualizaciones en una ubicación temporal.
  4. Ejecuta Updater2.exe con ShellExecuteEx y el verbo 'runas'.

Updater2.exe

  1. obtendrá evalated el UAC si los usuarios confirma la pronta o no se llevará a cabo en absoluto.
  2. Puede copiar los archivos de la ubicación temporal a la ubicación final.

Esto tiene varias ventajas:

  • El Updater2 sólo contiene las operaciones mínimas que tienen que correr elevado.
  • The Updater2 puede ser parte de los archivos que se descargan.
  • No es necesario comprobar ningún privilegio, UAC se encarga de eso.

También funciona en Windows XP, se le presenta un diálogo de inicio de sesión si no es un administrador.

2

Jwscl (La Biblioteca de seguridad de Windows Jedi) tiene una función para esto: JwCheckAdministratorAccess.

uso
function JwCheckAdministratorAccess: boolean; 

es muy simple:

Uses 
    JwsclToken; 

IsElevated := JwCheckAdministratorAccess; 

Esta función también funciona en Windows Vista y más adelante, si UAC está habilitado. Si el proceso actual no es elevado, el valor de retorno es falso incluso si el token contiene el grupo de administradores (que luego está deshabilitado). Esta función detecta una pertenencia a un grupo en el grupo de administradores, lo que significa que el usuario no necesita estar directamente en el grupo de administradores, sino que un grupo puede ser miembro del grupo de administradores.

+0

Perdón por responder a una pregunta anterior, no estoy seguro de cómo llegué aquí, pero no me di cuenta – Remko

2

He probado este código con Delphi 7, en Windows XP, 7 y 8 (admin y cuentas limitadas):

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; 
Cuestiones relacionadas