none
¿Por qué al ejecutar este código me dice que "la operación solicitada requiere elevación"? RRS feed

  • Pregunta

  • Intento ejecutar un programa que requiere ejecutarse como Administrador. En el manifest del programa he cambiado la línea para que el programa que lo lanza se ejecute con privilegios de Administrador.

    Lo que trato de hacer es ejecutar un programa con privilegios de administrador desde un usuario cuya cuenta es estándar pero

    en el código le indico una cuenta y una contraseña de un usuario que es Administrador ¿no se supone que si las credenciales son de Administrador debería ejecutar el programa que requiere privilegios de administrador? ¿por qué dice que la operación solicitada requiere elevación? además al poner en el app.manifest "requireAdministrator" VB se reinicia para cargar como Administrador, entonces por qué sale ese mensaje?

    NOTA: Estoy seguro que el usuario y la contraseña están bien porque si ejecuto el mismo código para un programa que no requiere privilegios de administrador lo ejecuta sin problemas y si modifico un caracter de la contraseña ya no lo ejecuta, genera error.

    With New Process
                    .StartInfo.FileName = Programa
                    .StartInfo.WorkingDirectory = "D:\"
                    .StartInfo.Password = Clave
                    .StartInfo.UserName = Usuario
                    .StartInfo.CreateNoWindow = False
                    .StartInfo.UseShellExecute = False
                    .Start()
                    .Close()
                End With



    martes, 1 de mayo de 2018 5:07

Respuestas

  • "James2016-2" escribió:

    > Lo que trato de hacer es ejecutar un programa con privilegios de administrador
    > desde un usuario cuya cuenta es estándar pero en el código le indico una cuenta
    > y una contraseña de un usuario que es Administrador ¿no se supone que si las
    > credenciales son de Administrador debería ejecutar el programa que requiere
    > privilegios de administrador? ¿por qué dice que la operación solicitada requiere
    > elevación? además al poner en el app.manifest "requireAdministrator" VB se
    > reinicia para cargar como Administrador, entonces por qué sale ese mensaje?

    Entiendo que ese mensaje de error se debe a la configuración del Control de Cuentas de Usuario (UAC) que tengas establecida en el sistema operativo, porque por mucho Administrador que seas, el propio sistema operativo muestra una serie de notificaciones para que explícitamente aceptes los cambios que pudiera hacer la aplicación que deseas ejecutar, por ponerte un simple ejemplo. Ahora bien, si en el UAC has decidido que no te muestre notificación alguna (cosa que no voy a ser yo el que te lo recomiende que hagas), pues no te aparecerá ninguna notificación cuando se intente instalar software nuevo o hacer cambios en la configuración del equipo.

    Por ejemplo, cada vez que deseo abrir el editor del registro de Windows, me aparece una notificación para que acepte si deseo permitir que esa aplicación haga cambios en el dispositivo. Si he iniciado sesión con una cuenta de Administrador, pues solo tengo que pulsar Sí o No, pero en cambio, si he iniciado sesión con una cuenta de Usuario normal y corriente, aparte de pulsar Sí o No, primeramente tengo que introducir de nuevo la contraseña del usuario.

    > En el manifest del programa he cambiado la línea para que el programa que lo lanza
    > se ejecute con privilegios de Administrador.

    Pues si en el manifiesto del ensamblado has indicado la siguiente línea:

        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

    ¿Para qué quieres ejecutar el nuevo proceso con las credenciales de un usuario concreto, con independencia que este último pertenezca o no al grupo Administradores?

    > With New Process
    >    .StartInfo.FileName = Programa
    >    .StartInfo.WorkingDirectory = "D:\"
    >    .StartInfo.Password = Clave
    >    .StartInfo.UserName = Usuario
    >    .StartInfo.CreateNoWindow = False
    >    .StartInfo.UseShellExecute = False
    >    .Start()
    >    .Close()
    > End With

    Si el programa que deseas ejecutar requiere hacerlo con privilegios administrativos, y el usuario que ha iniciado tu aplicación es Administrador, entiendo que no tienes que indicarle de nuevo las credenciales de la cuenta del usuario Administrador.

    Haz una prueba ejecutando lo siguiente:

           Try
                Dim info As New ProcessStartInfo(Ruta del programa que deseas ejecutar)
                info.WorkingDirectory = "D:\"
    
                Using p As New Process()
                    p.StartInfo = info
                    p.Start()
                    p.Close()
                End Using
    
            Catch ex As Exception
                ' Se ha producido un error.
                MessageBox.Show(ex.Message)
    
            End Try

    Observa que la única información que hemos utilizado es la ruta del programa y el directorio de trabajo; las restantes propiedades del objeto ProcessStartInfo tendrán su valor predeterminado.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.




    martes, 1 de mayo de 2018 8:16
    Moderador

Todas las respuestas

  • "James2016-2" escribió:

    > Lo que trato de hacer es ejecutar un programa con privilegios de administrador
    > desde un usuario cuya cuenta es estándar pero en el código le indico una cuenta
    > y una contraseña de un usuario que es Administrador ¿no se supone que si las
    > credenciales son de Administrador debería ejecutar el programa que requiere
    > privilegios de administrador? ¿por qué dice que la operación solicitada requiere
    > elevación? además al poner en el app.manifest "requireAdministrator" VB se
    > reinicia para cargar como Administrador, entonces por qué sale ese mensaje?

    Entiendo que ese mensaje de error se debe a la configuración del Control de Cuentas de Usuario (UAC) que tengas establecida en el sistema operativo, porque por mucho Administrador que seas, el propio sistema operativo muestra una serie de notificaciones para que explícitamente aceptes los cambios que pudiera hacer la aplicación que deseas ejecutar, por ponerte un simple ejemplo. Ahora bien, si en el UAC has decidido que no te muestre notificación alguna (cosa que no voy a ser yo el que te lo recomiende que hagas), pues no te aparecerá ninguna notificación cuando se intente instalar software nuevo o hacer cambios en la configuración del equipo.

    Por ejemplo, cada vez que deseo abrir el editor del registro de Windows, me aparece una notificación para que acepte si deseo permitir que esa aplicación haga cambios en el dispositivo. Si he iniciado sesión con una cuenta de Administrador, pues solo tengo que pulsar Sí o No, pero en cambio, si he iniciado sesión con una cuenta de Usuario normal y corriente, aparte de pulsar Sí o No, primeramente tengo que introducir de nuevo la contraseña del usuario.

    > En el manifest del programa he cambiado la línea para que el programa que lo lanza
    > se ejecute con privilegios de Administrador.

    Pues si en el manifiesto del ensamblado has indicado la siguiente línea:

        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

    ¿Para qué quieres ejecutar el nuevo proceso con las credenciales de un usuario concreto, con independencia que este último pertenezca o no al grupo Administradores?

    > With New Process
    >    .StartInfo.FileName = Programa
    >    .StartInfo.WorkingDirectory = "D:\"
    >    .StartInfo.Password = Clave
    >    .StartInfo.UserName = Usuario
    >    .StartInfo.CreateNoWindow = False
    >    .StartInfo.UseShellExecute = False
    >    .Start()
    >    .Close()
    > End With

    Si el programa que deseas ejecutar requiere hacerlo con privilegios administrativos, y el usuario que ha iniciado tu aplicación es Administrador, entiendo que no tienes que indicarle de nuevo las credenciales de la cuenta del usuario Administrador.

    Haz una prueba ejecutando lo siguiente:

           Try
                Dim info As New ProcessStartInfo(Ruta del programa que deseas ejecutar)
                info.WorkingDirectory = "D:\"
    
                Using p As New Process()
                    p.StartInfo = info
                    p.Start()
                    p.Close()
                End Using
    
            Catch ex As Exception
                ' Se ha producido un error.
                MessageBox.Show(ex.Message)
    
            End Try

    Observa que la única información que hemos utilizado es la ruta del programa y el directorio de trabajo; las restantes propiedades del objeto ProcessStartInfo tendrán su valor predeterminado.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.




    martes, 1 de mayo de 2018 8:16
    Moderador
  • Antes que nada gracias por la respuesta. Puse el código proporcionado en el evento clic de un botón y efectivamente funciona, el tema es que obviamente antes de ejecutarlo solicita las credenciales de administrador.

    Me pregunta

    ¿Para qué quieres ejecutar el nuevo proceso con las credenciales de un usuario concreto, con independencia que este último pertenezca o no al grupo Administradores?

    Es que la cuenta en la que trabajo es una cuenta estándar, entonces al ejecutar un programa que requiere elevación necesariamente Windows solicta las credenciales de la cuenta de Administrador (ya sea que lo ejecute directamente desde Windows o vía código) por esa razón trato de ejecutar el proceso a través de esa cuenta específica. Cabe mencionar que ambas cuentas residen en el mismo equipo y a ambas tengo acceso.

    Lo que quiero es ejecutar el programa directamente (en la cuenta estándar) sin que me pida las credenciales, pude hacer eso corriendo el programa vía código de VB a través de RunAs pero para ello las credenciales de administrador quedan guardadas en el equipo y no me gusta mucho la idea. Claro, por razones de seguridad la idea tampoco es desactivar UAC.

    Por eso pensé que al ponerlas directamente en los parámetros de StartInfo ya no requeriría elevación, o sea que correría como RunAs pero veo que no es así.

    En todo caso ¿habrá alguna alternativa a RunAs para correr el programa vía código proporcionándole previamente las credenciales para que no me las pida al ejecutarlo?



    martes, 1 de mayo de 2018 19:23
  • P. D. Me olvidé de comentar, respecto a lo que me dice:

    "Si el programa que deseas ejecutar requiere hacerlo con privilegios administrativos, y el usuario que ha iniciado tu aplicación es Administrador, entiendo que no tienes que indicarle de nuevo las credenciales de la cuenta del usuario Administrador."

    Claro, si ejecuto el mismo código que me proporcionó indicando en el archivo de manifiesto esta línea:

      <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

    Me pide las credenciales cuando VB se reinicia porque corre desde una cuenta estándar y luego al ejecutar el programa,

    ya no me pide las credenciales, como dice, porque las ingresé en el momento que VB se reinicia, pero si por ejemplo corro el ejecutable directamente allí sí las pide y está bien porque como lo ejecuto de una cuenta estándar y necesita elevación tengo que ingresar las credenciales de la cuenta de administrador. Hasta allí todo bien y entiendo lo que me comenta, el problema es lo que explico en el otro comentario.



    martes, 1 de mayo de 2018 19:31
  • "James2016-2" preguntó:

    > Lo que quiero es ejecutar el programa directamente (en la cuenta estándar) sin que me
    > pida las credenciales, pude hacer eso corriendo el programa vía código de VB a través
    > de RunAs pero para ello las credenciales de administrador quedan guardadas en el equipo
    > y no me gusta mucho la idea. Claro, por razones de seguridad la idea tampoco es desactivar UAC.
    >
    > En todo caso ¿habrá alguna alternativa a RunAs para correr el programa vía código
    > proporcionándole previamente las credenciales para que no me las pida al ejecutarlo?

    Ignoro si habrá alguna altenativa a "RunAs" que evite tener que especificar las credenciales de alguna cuenta de usuario perteneciente al grupo Administradores.

    ¡Vamos a ver! Si una cuenta de usuario estándar desea ejecutar un programa que requiere la cuenta de un usuario Administrador, tienes dos opciones, al menos que yo sepa:

        - Especificar en el manifiesto del ensamblado la siguiente opción:

          <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

          para que el usuario escriba las credenciales de una cuenta del grupo Administradores si no pertenece a dicho grupo.

        - O bien, hacer uso de la función CreateProcessWithLogon perteneciente a la API de Windows, que es la que nos permite suplantar (impersonate) a otro usuario para ejecutar un programa en el contexto de seguridad que dicho usuario disponga, en el caso que nos ocupa, en el contexto de seguridad de un usuario Administrador, lo que en el entorno Microsoft Windows se conoce normalmente con Ejecutar como administrador (Run as administrator).

    Pero el inconveniente que tiene la función CreateProcessWithLogon es que necesitas especificar en el código las credenciales del usuario al que se desea suplantar. ¿Que no las quieres escribir en el código porque estas pueden ser diferentes en un equipo u otro, o pueden cambiar con el tiempo? Tendrás que habilitar un cuadro de diálogo para que el usuario las escriba, pero en este caso, estaríamos en las mismas circunstancias que con el cuadro de diálogo que muestra el UAC.

    En definitiva, que si no deseas poner en riesgo la seguridad del sistema operativo, la de la organización a la que pertenece el usuario, o la de tu propia aplicación, y siempre y cuando esta última esté diseñada para ser ejecutada por un miembro del grupo Administradores, no te va a quedar más remedio que mostrarle al usuario un cuadro de diálogo (propio o el que muestra el UAC) para que introduzca las credenciales del usuario al cual se desea sumplantar.

    Cuando diseñamos una aplicación para que solamente pueda ser ejecutada por usuarios del grupo Administradores, es porque se trata de la típica aplicación administrativa que ejecuta una serie de acciones que el propio sistema operativo no permite que la ejecute una cuenta de usuario no perteneciente al grupo Administradores. Es por ello por lo que modificamos el manifiesto del ensamblado y especificamos el nivel "requireAdministrator", por si algún "usuario curioso" la ejecuta que sepa que tiene que especificar las credenciales de un usuario Administrador. ¿Que no la especifica? La aplicación finalizará sin más. Pero, ¿qué sucedería si el manifiesto no contiene el requerimiento de Administrador y un usuario NO Admistrador la ejecuta? Pues que la aplicación finalizará bruscamente cuando llegue al punto de querer ejecutar una acción que requiere de unos permisos más elevados que los que realmente dispone el usuario actual.

    Las aplicaciones se diseñan para que sean ejecutadas por el mayor número de usuarios posible sin poner en peligro, ni la seguridad del sistema operativo, y menos aún, la seguridad del propio entorno corporativo a la que pertenezcan los usuarios. Pero al tratarse de una aplicación administrativa, es por lo que obligamos a la misma a requerir las credenciales de un usuario Administrador SOLAMENTE si el usuario que ha iniciado la aplicación no pertenece al grupo Administradores.

    Si el usuario que ejecuta la aplicación pertenece al grupo Administradores, como mucho tendrá que responder o No a la notificación que muestra el UAC. Pero si no pertenece a dicho grupo, aparte de responder o No, también tendrá que especificar las credenciales de un usuario Administrador en cuyo contexto de seguridad se ejecutará, tanto la propia aplicación como aquellos otros procesos que se ejecuten desde la misma (el caso del método Process.Start por el que iniciastes esta conversación).


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.



    miércoles, 2 de mayo de 2018 10:08
    Moderador
  • Buenas, entiendo lo que dice respecto a la seguridad y cuándo se requiere o no ingresar las credenciales.

    Le cuento lo que trato de hacer, lo que quiero y lo que no a ver si me puede dar alguna idea:

    El equipo en el que trabajo lo he configurado para trabajar en una cuenta estándar, adicionalmente tiene configurada una cuenta de administrador, trabajo en la cuenta estándar y todo lo hago desde allí, así cuando requiero por ejemplo ejecutar una consola de administrador, simplemente ingreso las credenciales y puedo hacer casi todo lo que podría hacer desde la cuenta de administrador, desde la consola puedo lanzar incluso utilidades como Administración de Discos.

    Lo que trato de hacer es lo siguiente: quiero monitorear los sensores de temperatura y cargar una utilidad para controlar el estado de las teclas Bloq Num y Bloq May, tengo las utilidades que lo hacen una propia y una instalada de terceros, la cosa es que necesitan ejecutarse como administrador, pero las cargo al inicio de Windows mediante una tarea programada, y como corren desde la cuenta estándar es engorroso estar especificando para cada una de esas tareas la contraseña cada vez que carga Windows, las configuré en un primer momento lanzandólas desde un exe que a su vez ejecutaba el RunAs pero, como comenté, las credenciales quedan en el equipo y entonces puede que una aplicación o un 'script' que ejecute el RunAs con el parámetro /SaveCred puede acceder al equipo como Pedro en su casa :-) jajaja

    Entonces lo que se me ocurre es explorar la posibilidad de especificar las credenciales en el mismo .exe, eso evitaría que quede guardada en el Administrador de Credenciales de Windows, claro que tampoco es muy seguro que digamos, pero al menos ya no se puede acceder a esta a través del parámetro /SaveCred de RunAs, en ese sentido creo que la API CreateProcessWithLogon podría servir si es que puedo poner directamente los parámetros ¿se puede?

    Por otro lado, he visto también que se puede configurar una directiva para ejecutar 'scripts' al inicio de Windows en una cuenta estándar y creo que al especificarla funcionan como una excepción, es decir no requiere elevación o algo así (se supone que se configura desde una cuenta de adminstrador), no sé si me puede comentar algo al respecto. Gracias por su paciencia, gracias por todo.

    miércoles, 2 de mayo de 2018 20:43
  • "James2016-2" preguntó:

    > Entonces lo que se me ocurre es explorar la posibilidad de especificar las credenciales
    > en el mismo .exe, eso evitaría que quede guardada en el Administrador de Credenciales de
    > Windows, claro que tampoco es muy seguro que digamos, pero al menos ya no se puede acceder
    > a esta a través del parámetro /SaveCred de RunAs, en ese sentido creo que la API
    > CreateProcessWithLogon podría servir si es que puedo poner directamente los parámetros
    > ¿se puede?

    Pues claro que se puede especificar directamente las credenciales de cualquier cuenta de usuario a la función CreateProcessWithLogon. En una conversación que aparece más abajo encontrarás un ejemplo publicado por mí:

    como abrir un archivo con shell con permisos de administrador

    Pero tampoco te voy aconsejar que en el propio ejecutable de tu aplicación aparezcan, como texto plano, las credenciales de un usuario Administrador, porque cualquier intruso podría leerlas perfectamente. Aparte que las contraseñas de las cuentas es conveniente cambiarlas al menos una vez al mes. Cuando el usuario Administrador cambie la contraseña, ¿qué haces? ¿Compilar y distribuir nuevamente tu aplicación para que tenga en cuenta la nueva contraseña del usuario Administrador?

    Me vas a perdonar, pero eso de diseñar una aplicación para que la ejecute una cuenta estándar que va a suplantar a una cuenta de Administrador, y encima las credenciales de éste figuran en el propio archivo ejecutable, personalmente no me convence a mí, y si yo fuera el responsable de seguridad de la organización donde se pretende ejecutar ese programa, te garantizo que el mismo no se instalaría en ningún equipo, porque la seguridad es lo principal. Así de claro te lo digo.

    > Lo que trato de hacer es lo siguiente: quiero monitorear los sensores de temperatura y
    > cargar una utilidad para controlar el estado de las teclas Bloq Num y Bloq May, tengo
    > las utilidades que lo hacen una propia y una instalada de terceros, la cosa es que
    > necesitan ejecutarse como administrador, ...

    Esos sensores de temperatura que deseas monitorizar, ¿no serán los de un "reactor nuclear"? :-))

    Bromas aparte, si es importante un control exhaustivo de la temperatura, lo mismo tendrías que pensarte en diseñar un servicio (en lugar de un ejecutable) para llevar a efecto dicha tarea, servicio que se deberá de iniciar al iniciarse el sistema operativo y con el que se comunicará tu aplicación. Por supuesto, ese servicio deberá de instalarse por una cuenta de usuario Administrador, por lo que una cuenta de usuario estándar con los permisos por defecto, no podrá pausarlo y menos aún detenerlo.

    > Por otro lado, he visto también que se puede configurar una directiva para ejecutar
    > 'scripts' al inicio de Windows en una cuenta estándar y creo que al especificarla
    > funcionan como una excepción, es decir no requiere elevación o algo así (se supone
    > que se configura desde una cuenta de adminstrador), no sé si me puede comentar algo
    > al respecto.

    Por configurar directivas, puedes configurar todas las que desees, siempre y cuando tengas permiso para ello. Pero creo que todo esto se sale fuera ya, tanto del asunto de la pregunta que iniciastes como del contenido del foro donde la publicastes, porque entiendo que tiene que ver más con el propio sistema operativo Windows que con programación con un lenguaje .NET concreto, por lo que mi consejo sería, si así lo estimas conveniente, que efectuases la pregunta en algún foro propio de Windows, como por ejemplo:

    Microsoft Answers - Windows 10

    Microsoft Technet - Windows 10 IT Pro


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    jueves, 3 de mayo de 2018 10:11
    Moderador
  • Ok, entiendo sus criterios respecto a la seguridad un punto a tener en cuenta.

    Le cuento que quiero monitorear la temperatura del procesador porque a veces trabajo con programas pesados, por allí Corel Draw o Photoshop y la temperatura se suele elevar drásticamente sobre todo en una notebook, por eso necesito chequearla constantemente.

    Le comento que estaba haciendo pruebas con la API en cuestión y efectivamente se pueden especificar los parámetros directamente, lo malo es que llego al mismo sitio, por mucho que le indique una cuenta de administrador, no tiene el mismo comportamiento que RunAs. Si el programa que intento ejecutar no necesita ejecutarse como administrador lo ejecuta sin problema suplantando la cuenta actual por la que especifique, pero si necesita elevación y lo corro desde una cuenta estándar, no lo ejecuta.

    Bueno seguiré probando e indagando. Gracias por todo. Saludos.

    jueves, 3 de mayo de 2018 23:07