Pregunta

Necesito que mi aplicación se comporte de manera diferente dependiendo de si Vista UAC está habilitado o no.¿Cómo puede mi aplicación detectar el estado de UAC en la computadora del usuario?

¿Fue útil?

Solución

Esta clave de registro debería indicarle:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

Valor EnableLUA (DWORD)

1 activado / 0 o desaparecido discapacitado

Pero eso supone que tienes los derechos para leerlo.

Mediante programación, puede intentar leer el token del usuario y adivinar si es un administrador que se ejecuta con UAC habilitado (consulte aquí).No es infalible, pero puede funcionar.

La cuestión aquí es más bien "por qué necesita saberlo": influye en la respuesta.Realmente, no existe una API porque, desde el punto de vista del comportamiento del sistema operativo, lo que importa es si el usuario es administrador o no: cómo elige protegerse como administrador es su problema.

Otros consejos

Esta publicación tiene un código de muestra en C# para probar si UAC está activado y si a la aplicación actual se le han otorgado derechos elevados.Puede descargar el código e interpretarlo según sea necesario.También vinculado hay una muestra que muestra lo mismo en C++

http://www.itwriting.com/blog/198-c-code-to-detect-uac-elevation-on-vista.html

El código de esa publicación no solo se lee del registro.Si UAC está habilitado, es probable que no tenga derechos para leerlo del registro.

No desea verificar si UAC está habilitado;eso no te dice nada.

Puedo ser un usuario estándar con UAC deshabilitado.

quieres comprobar si el usuario está ejecutando con privilegios administrativos usando CheckTokenMembership:

///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 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 depricated, 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 caller's
        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;

Puedes hacerlo examinando el valor DWORD. HabilitarLUA en la siguiente clave de registro:

HKLM/SOFTWARE/Microsoft/Windows/Versión actual/Políticas/Sistema

Si el valor es 0 (o no existe), entonces el UAC está APAGADO.Si está presente y es distinto de cero, entonces UAC está activado:

BOOL IsUacEnabled( )
{
    LPCTSTR pszSubKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
    LPCTSTR pszValue = _T("EnableLUA");
    DWORD dwType = 0;
    DWORD dwValue = 0;
    DWORD dwValueSize = sizeof( DWORD );

    if ( ERROR_SUCCESS != SHGetValue( HKEY_LOCAL_MACHINE, pszSubKey, pszValueOn, 
        &dwType, &dwValue, &dwValueSize) )
    {
            return FALSE;
    }

    return dwValue != 0;
} 

Tenga en cuenta que si el usuario ha cambiado el estado de UAC pero aún no ha reiniciado la computadora, esta función devolverá un resultado inconsistente.

Compruebe el valor del registro en HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

El valor EnableLUA determina si UAC está activo.

Esta publicación es bastante antigua, pero quería comentar sobre las partes "por qué necesita saberlo" y "verificar la membresía del token".

El hecho es que la propia documentación de Microsoft dice que "Si el Control de cuentas de usuario se ha desactivado y un usuario estándar intenta realizar una tarea que requiere elevación", deberíamos proporcionar un error en lugar de mostrar botones y/o enlaces con el escudo UAC que intentar la elevación.Ver http://msdn.microsoft.com/en-us/library/windows/desktop/aa511445.aspx hacia abajo para los detalles.

¿Cómo hacemos con esto sin una forma de verificar si UAC está habilitado?

Quizás comprobar si el usuario está ejecutando con privilegios de administrador sea lo correcto en este caso, pero ¿quién sabe?La guía que brinda Microsoft es, a lo mejor, dudoso, si no simplemente confuso.

Para cualquier otra persona que encuentre esto y esté buscando una solución VBScript.Esto es lo que se me ocurrió para detectar si UAC está habilitado y, de ser así, reiniciar mi script con privilegios elevados.Simplemente coloque su código en la función Body().Descubrí que había problemas con la transportabilidad entre XP y Windows 7 si escribía código para iniciar siempre elevado.Con este método, evito la elevación si no hay UAC.También se deben tener en cuenta las versiones de servidor de 2008 y posteriores que tienen UAC habilitado.

On Error Resume Next
UACPath = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA"
Dim WshShell
Set WshShell = CreateObject("wscript.Shell")
UACValue = WshShell.RegRead(UACPath)
If UACValue = 1 Then
'Run Elevated
    If WScript.Arguments.length =0 Then
      Set objShell = CreateObject("Shell.Application")
      'Pass a bogus argument with leading blank space, say [ uac]
      objShell.ShellExecute "wscript.exe", Chr(34) & _
      WScript.ScriptFullName & Chr(34) & " uac", "", "runas", 1
      WScript.Quit
    Else 
        Body()
    End If
Else
Body()
End If

Function Body()
MsgBox "This is the body of the script"
End Function

AFAIK, UAC es una configuración de política para el usuario o grupo local.Para que pueda leer esta propiedad desde .Net.Perdón por no tener más detalles pero espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top