none
como abrir un archivo con shell con permisos de administrador

    Pregunta

  • hola de nuevo
    en un programa uso la sentencia shell para ejecutar un archivo pero para que el archivo funcione se nesecita abrir como administrador ¿Como le hago para que vb pida el permiso y lo use para abrir ese archivo?
    gracias 
    saludos
    viernes, 14 de agosto de 2009 2:13

Respuestas

  • Me he entretenido en preparte un ejemplo para ejecutar una aplicación con una cuenta de otro usuario, utilizando la función «CreateProcessWithLogonW» de la API de Windows.

    Crea un módulo en tu proyecto, y copia/pega el siguiente código:

    Imports System.Runtime.InteropServices
    Imports System.ComponentModel
    
    Module Module1
    
    #Region "Constantes, Estructura y Funciones de la API"
    
        Private WAIT_INFINITE As System.UInt32 = Convert.ToUInt32(&HFFFFFFF)
        'Private Const WAIT_INFINITE As Int32 = &HFFFFFFFF
    
        Private Const STILL_ACTIVE As Int32 = &H103
    
        Private Const LOGON_WITH_PROFILE As Int32 = &H1
        Private Const LOGON_NETCREDENTIALS_ONLY As Int32 = &H2
        Private Const CREATE_DEFAULT_ERROR_MODE As Int32 = &H4000000
        Private Const CREATE_NEW_CONSOLE As Int32 = &H10
        Private Const CREATE_NEW_PROCESS_GROUP As Int32 = &H200
        Private Const CREATE_SEPARATE_WOW_VDM As Int32 = &H800
        Private Const CREATE_SUSPENDED As Int32 = &H4
        Private Const CREATE_UNICODE_ENVIRONMENT As Int32 = &H400
        Private Const ABOVE_NORMAL_PRIORITY_CLASS As Int32 = &H8000
        Private Const BELOW_NORMAL_PRIORITY_CLASS As Int32 = &H4000
        Private Const HIGH_PRIORITY_CLASS As Int32 = &H80
        Private Const IDLE_PRIORITY_CLASS As Int32 = &H40
        Private Const NORMAL_PRIORITY_CLASS As Int32 = &H20
        Private Const REALTIME_PRIORITY_CLASS As Int32 = &H100
    
        Private Const SW_HIDE As Int32 = 0
        Private Const STARTF_USESHOWWINDOW As Int32 = &H1
    
        Private processInfo As New PROCESS_INFORMATION()
        Private startInfo As New STARTUPINFO()
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure PROCESS_INFORMATION
            Friend hProcess As IntPtr
            Friend hThread As IntPtr
            Friend dwProcessId As Int32
            Friend dwThreadId As Int32
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure STARTUPINFO
            Friend cb As Int32
            Friend lpReserved As IntPtr
            Friend lpDesktop As IntPtr
            Friend lpTitle As IntPtr
            Friend dwX As Int32
            Friend dwY As Int32
            Friend dwXSize As Int32
            Friend dwYSize As Int32
            Friend dwXCountChars As Int32
            Friend dwYCountChars As Int32
            Friend dwFillAttribute As Int32
            Friend dwFlags As Int32
            Friend wShowWindow As Short
            Friend cbReserved2 As Short
            Friend lpReserved2 As IntPtr
            Friend hStdInput As IntPtr
            Friend hStdOutput As IntPtr
            Friend hStdError As IntPtr
        End Structure
    
        <Flags()> _
       Private Enum HANDLE_TYPES
            STD_INPUT_HANDLE = -10
            STD_OUTPUT_HANDLE = -11
            STD_ERROR_HANDLE = -12
        End Enum
    
        <Flags()> _
       Private Enum START_UP_INFO_FLAGS
            STARTF_USESHOWWINDOW = &H1
            STARTF_USESIZE = &H2
            STARTF_USEPOSITION = &H4
            STARTF_USECOUNTCHARS = &H8
            STARTF_USEFILLATTRIBUTE = &H10
            STARTF_RUNFULLSCREEN = &H20
            STARTF_FORCEONFEEDBACK = &H40
            STARTF_FORCEOFFFEEDBACK = &H80
            STARTF_USESTDHANDLES = &H100
        End Enum
    
        <DllImport("Kernel32.dll", SetLastError:=True)> _
        Private Function CloseHandle(ByVal handle As IntPtr) As Boolean
            ' Sin código de implementación
        End Function
    
        <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
        Private Function CreateProcessWithLogonW( _
                ByVal lpUsername As String, _
                ByVal lpDomain As String, _
                ByVal lpPassword As String, _
                ByVal dwLogonFlags As UInt32, _
                ByVal lpApplicationName As String, _
                ByVal lpCommandLine As String, _
                ByVal dwCreationFlags As UInt32, _
                ByVal lpEnvironment As UIntPtr, _
                ByVal lpCurrentDirectory As String, _
                ByRef lpStartupInfo As STARTUPINFO, _
                ByRef lpProcessInfo As PROCESS_INFORMATION) As Int32
            ' Sin código de implementación
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)> _
        Private Function GetExitCodeProcess( _
            ByVal hProcess As IntPtr, _
            ByRef lpExitCode As UInt32) As Int32
            ' Sin código de implementación
        End Function
    
        <DllImport("Kernel32.dll", SetLastError:=True)> _
        Private Function GetStdHandle(ByVal nStdHandle As IntPtr) As IntPtr
            ' Sin código de implementación
        End Function
    
        <DllImport("Kernel32.dll", SetLastError:=True)> _
        Private Function WaitForSingleObject( _
            ByVal handle As IntPtr, _
            ByVal milliseconds As UInt32) As UInt32
            ' Sin código de implementación
        End Function
    
        Friend Function RunAs( _
            ByVal application As String, _
            ByVal commandLine As String, _
            ByVal userName As String, _
            ByVal password As String, _
            ByVal domain As String, _
            ByVal hide As Boolean) As UInt32
    
            Dim si As STARTUPINFO
            Dim piProcess As PROCESS_INFORMATION
            Dim intReturn As Int32
            Dim exitCode As UInt32
            Dim currentDirectory As String = IO.Directory.GetCurrentDirectory
    
            If (commandLine Is Nothing) Then commandLine = String.Empty
    
            si.cb = Marshal.SizeOf(si)
    
            If (hide) Then
                si.dwFlags = STARTF_USESHOWWINDOW
                si.wShowWindow = SW_HIDE
            End If
    
            Try
                intReturn = CreateProcessWithLogonW( _
                    userName, _
                    domain, _
                    password, _
                    LOGON_WITH_PROFILE, _
                    application, _
                    commandLine, _
                    NORMAL_PRIORITY_CLASS Or _
                        CREATE_DEFAULT_ERROR_MODE Or _
                        CREATE_NEW_CONSOLE Or _
                        CREATE_NEW_PROCESS_GROUP, _
                    UIntPtr.Zero, _
                    currentDirectory, _
                    si, _
                    piProcess)
    
                If (intReturn = 0) Then
                    intReturn = Err.LastDllError
                    Throw New Win32Exception(Marshal.GetLastWin32Error())
                End If
    
                ' Esperar a que finalice la aplicación
                '
                Call WaitForSingleObject(piProcess.hProcess, WAIT_INFINITE)
    
                ' Obtenemos el valor de retorno
                '
                Dim ret As Int32 = GetExitCodeProcess(piProcess.hProcess, exitCode)
    
                Return exitCode
    
            Finally
                ' Cerrar el manipulador del proceso
                CloseHandle(piProcess.hProcess)
    
                ' Cerrar el manipulador del subproceso creado
                CloseHandle(piProcess.hThread)
    
            End Try
    
        End Function
    
    #End Region
    
    End Module

    Cuando desees ejecutar un programa utilizando la cuenta de otro usuario, del cual tendrás que conocer la contraseña, escribe lo siguiente:

        Try
            Dim ret As UInt32 = _
                RunAs("C:\Carpeta\Programa.exe", "", "Administrador", "contraseña", "", False)
    
            MessageBox.Show(ret.ToString())
    
        Catch ex As Exception
            MessageBox.Show(ex.Message)
    
        End Try

    Te advierto que la función RunAs no finalizará hasta que finalice la aplicación que has ejecutado, ya que se hace uso de la función API «WaitForSingleObject».

    Recuerda marcar la respuesta como satisfactoria si la misma te ha sido útil.


    Enrique Martínez [MS MVP - VB]

    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.

    sábado, 15 de agosto de 2009 12:12
    Moderador

Todas las respuestas

  • ¡Uy! Eso no es tan sencillo de realizar, porque en primer lugar, tendrás que capturar el contexto de seguridad de un Administrador del sistema, lo que significa que tendrás que conocer de antemano la contraseña del Administrador, para poder ejecutar la aplicación con los permisos de dicho usuario.

    Para que más o menos te hagas una idea, es como seleccionar la opción "Ejecutar como..." cuando deseamos ejecutar un archivo utilizando la cuenta de otro usuario.

    Ahora bien, si eres capaz de capturar el contexto de seguridad de un usuario Administrador, entiendo que no tendrás inconveniente alguno para ejecutar cualquier proceso en su nombre. :-)

    Como éste es un tema bastante complicado de explicar por éste medio, te remito a que le eches un vistazo al siguiente enlace, para que adaptes (repito PARA QUE ADAPTES) su contenido a tus necesidades:

    Cómo verificar la cuenta de usuario de Windows
    http://mvp-access.es/softjaen/vbnet/funciones/security/sjvbnetsec01.htm

    También te aconsejaría que abrieras la ayuda de Visual Studio, y buscaras la clase SecurityContext, dentro del espacio de nombres System.Security, donde también encontrarás un ejemplo para capturar el contexto de seguridad de cualquier usuario, siempre y cuando conozcas su contraseña, claro está.

    ¡Suerte!




    Enrique Martínez [MS MVP - VB]
    viernes, 14 de agosto de 2009 6:42
    Moderador
  • :-)
    Hola Emilio,

    Para poder hacer esto debes usar Impersonation, es decir, que tu aplicación suplante momentáneamente los permisos de otro usuario con distintos privilegios. Básicamente el proceso sería:

    - Tu aplicación crea un contexto de suplantación con los permisos de otro usuario (administrador)
    - Lanzas el proceso deseado, que se ejecutará con los nuevos credenciales
    - Destruyes el contexto de suplantación y vuelves a tu contexto de usuario.

    Hace un tiempo escribí un post al respecto. Dale un vistazo y me cuentas:
    http://geeks.ms/blogs/lfranco/archive/2008/05/26/acceder-a-la-cach-233-de-internet-explorer-iii.aspx

    Saludos,

    No olvides marcar la respuesta como correcta si te ha sido de utilidad :-)

    [MS-MVP-MCTS]

    Mi Perfil MVP en: https://mvp.support.microsoft.com/profile/Lluis
    NUG: http://andorradotnet.com
    Web: http://www.ordeeno.com
    Blog: http://msmvps.com/blogs/lfranco
    Geeks: http://geeks.ms/blogs/lfranco

    viernes, 14 de agosto de 2009 9:32
    Moderador
  • muchas gracias pero no se como adaptarlo a mis necesidades, no soy tan avanzado. si me explicaras a hacerlo te agradececeria pero sino puedes, tengo otra pregunta:
    la otra forma seria decirles a los usuarios del programa lo abran como admin. pero el archivo que crea la publicacion no tiene esa opcion, solo sale take ownership (tengo windows en ingles) en cambio en el exe de la carpeta bin del proyecto si sale run as administrator y funciona pero en otras comutadoras no se abre, recuerdo que hay que instalar algo de microsoft pero no me acuerdo de como se llama, ¿me podrias decir porfavor?
    muchas gracias
    viernes, 14 de agosto de 2009 15:55
  • Si quieres un consejo, dedícate a diseñar aplicaciones que puedan ser ejecutadas por cualquier usuario, sin necesidad de que su cuenta tenga privilegios de Administrador. No sabes lo molesto que es el Control de Cuentas de Usuario de Windows Vista y de Windows 7, cada vez que se desea ejecutar una aplicación que requiere una elevación de pemisos.

    Ahora bien, si solamente deseas que tu programa lo ejecuten los propios Admistradores del sistema, entonces, muy bien: con hacérselo saber a ellos es más que suficiente: ¡Este programa sólo funciona con cuentas de Administrador!

    En cuanto a la pregunta que me estás haciendo, ignoro qué es lo que hay que instalar en el sistema para que funcione. Si el sistema operativo es Windows 2000 o superior, entiendo que existe la opción Ejecutar cómo..., o Run As..., en inglés.

    Enrique Martínez [MS MVP - VB]
    sábado, 15 de agosto de 2009 11:24
    Moderador
  • Me he entretenido en preparte un ejemplo para ejecutar una aplicación con una cuenta de otro usuario, utilizando la función «CreateProcessWithLogonW» de la API de Windows.

    Crea un módulo en tu proyecto, y copia/pega el siguiente código:

    Imports System.Runtime.InteropServices
    Imports System.ComponentModel
    
    Module Module1
    
    #Region "Constantes, Estructura y Funciones de la API"
    
        Private WAIT_INFINITE As System.UInt32 = Convert.ToUInt32(&HFFFFFFF)
        'Private Const WAIT_INFINITE As Int32 = &HFFFFFFFF
    
        Private Const STILL_ACTIVE As Int32 = &H103
    
        Private Const LOGON_WITH_PROFILE As Int32 = &H1
        Private Const LOGON_NETCREDENTIALS_ONLY As Int32 = &H2
        Private Const CREATE_DEFAULT_ERROR_MODE As Int32 = &H4000000
        Private Const CREATE_NEW_CONSOLE As Int32 = &H10
        Private Const CREATE_NEW_PROCESS_GROUP As Int32 = &H200
        Private Const CREATE_SEPARATE_WOW_VDM As Int32 = &H800
        Private Const CREATE_SUSPENDED As Int32 = &H4
        Private Const CREATE_UNICODE_ENVIRONMENT As Int32 = &H400
        Private Const ABOVE_NORMAL_PRIORITY_CLASS As Int32 = &H8000
        Private Const BELOW_NORMAL_PRIORITY_CLASS As Int32 = &H4000
        Private Const HIGH_PRIORITY_CLASS As Int32 = &H80
        Private Const IDLE_PRIORITY_CLASS As Int32 = &H40
        Private Const NORMAL_PRIORITY_CLASS As Int32 = &H20
        Private Const REALTIME_PRIORITY_CLASS As Int32 = &H100
    
        Private Const SW_HIDE As Int32 = 0
        Private Const STARTF_USESHOWWINDOW As Int32 = &H1
    
        Private processInfo As New PROCESS_INFORMATION()
        Private startInfo As New STARTUPINFO()
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure PROCESS_INFORMATION
            Friend hProcess As IntPtr
            Friend hThread As IntPtr
            Friend dwProcessId As Int32
            Friend dwThreadId As Int32
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure STARTUPINFO
            Friend cb As Int32
            Friend lpReserved As IntPtr
            Friend lpDesktop As IntPtr
            Friend lpTitle As IntPtr
            Friend dwX As Int32
            Friend dwY As Int32
            Friend dwXSize As Int32
            Friend dwYSize As Int32
            Friend dwXCountChars As Int32
            Friend dwYCountChars As Int32
            Friend dwFillAttribute As Int32
            Friend dwFlags As Int32
            Friend wShowWindow As Short
            Friend cbReserved2 As Short
            Friend lpReserved2 As IntPtr
            Friend hStdInput As IntPtr
            Friend hStdOutput As IntPtr
            Friend hStdError As IntPtr
        End Structure
    
        <Flags()> _
       Private Enum HANDLE_TYPES
            STD_INPUT_HANDLE = -10
            STD_OUTPUT_HANDLE = -11
            STD_ERROR_HANDLE = -12
        End Enum
    
        <Flags()> _
       Private Enum START_UP_INFO_FLAGS
            STARTF_USESHOWWINDOW = &H1
            STARTF_USESIZE = &H2
            STARTF_USEPOSITION = &H4
            STARTF_USECOUNTCHARS = &H8
            STARTF_USEFILLATTRIBUTE = &H10
            STARTF_RUNFULLSCREEN = &H20
            STARTF_FORCEONFEEDBACK = &H40
            STARTF_FORCEOFFFEEDBACK = &H80
            STARTF_USESTDHANDLES = &H100
        End Enum
    
        <DllImport("Kernel32.dll", SetLastError:=True)> _
        Private Function CloseHandle(ByVal handle As IntPtr) As Boolean
            ' Sin código de implementación
        End Function
    
        <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
        Private Function CreateProcessWithLogonW( _
                ByVal lpUsername As String, _
                ByVal lpDomain As String, _
                ByVal lpPassword As String, _
                ByVal dwLogonFlags As UInt32, _
                ByVal lpApplicationName As String, _
                ByVal lpCommandLine As String, _
                ByVal dwCreationFlags As UInt32, _
                ByVal lpEnvironment As UIntPtr, _
                ByVal lpCurrentDirectory As String, _
                ByRef lpStartupInfo As STARTUPINFO, _
                ByRef lpProcessInfo As PROCESS_INFORMATION) As Int32
            ' Sin código de implementación
        End Function
    
        <DllImport("kernel32.dll", SetLastError:=True)> _
        Private Function GetExitCodeProcess( _
            ByVal hProcess As IntPtr, _
            ByRef lpExitCode As UInt32) As Int32
            ' Sin código de implementación
        End Function
    
        <DllImport("Kernel32.dll", SetLastError:=True)> _
        Private Function GetStdHandle(ByVal nStdHandle As IntPtr) As IntPtr
            ' Sin código de implementación
        End Function
    
        <DllImport("Kernel32.dll", SetLastError:=True)> _
        Private Function WaitForSingleObject( _
            ByVal handle As IntPtr, _
            ByVal milliseconds As UInt32) As UInt32
            ' Sin código de implementación
        End Function
    
        Friend Function RunAs( _
            ByVal application As String, _
            ByVal commandLine As String, _
            ByVal userName As String, _
            ByVal password As String, _
            ByVal domain As String, _
            ByVal hide As Boolean) As UInt32
    
            Dim si As STARTUPINFO
            Dim piProcess As PROCESS_INFORMATION
            Dim intReturn As Int32
            Dim exitCode As UInt32
            Dim currentDirectory As String = IO.Directory.GetCurrentDirectory
    
            If (commandLine Is Nothing) Then commandLine = String.Empty
    
            si.cb = Marshal.SizeOf(si)
    
            If (hide) Then
                si.dwFlags = STARTF_USESHOWWINDOW
                si.wShowWindow = SW_HIDE
            End If
    
            Try
                intReturn = CreateProcessWithLogonW( _
                    userName, _
                    domain, _
                    password, _
                    LOGON_WITH_PROFILE, _
                    application, _
                    commandLine, _
                    NORMAL_PRIORITY_CLASS Or _
                        CREATE_DEFAULT_ERROR_MODE Or _
                        CREATE_NEW_CONSOLE Or _
                        CREATE_NEW_PROCESS_GROUP, _
                    UIntPtr.Zero, _
                    currentDirectory, _
                    si, _
                    piProcess)
    
                If (intReturn = 0) Then
                    intReturn = Err.LastDllError
                    Throw New Win32Exception(Marshal.GetLastWin32Error())
                End If
    
                ' Esperar a que finalice la aplicación
                '
                Call WaitForSingleObject(piProcess.hProcess, WAIT_INFINITE)
    
                ' Obtenemos el valor de retorno
                '
                Dim ret As Int32 = GetExitCodeProcess(piProcess.hProcess, exitCode)
    
                Return exitCode
    
            Finally
                ' Cerrar el manipulador del proceso
                CloseHandle(piProcess.hProcess)
    
                ' Cerrar el manipulador del subproceso creado
                CloseHandle(piProcess.hThread)
    
            End Try
    
        End Function
    
    #End Region
    
    End Module

    Cuando desees ejecutar un programa utilizando la cuenta de otro usuario, del cual tendrás que conocer la contraseña, escribe lo siguiente:

        Try
            Dim ret As UInt32 = _
                RunAs("C:\Carpeta\Programa.exe", "", "Administrador", "contraseña", "", False)
    
            MessageBox.Show(ret.ToString())
    
        Catch ex As Exception
            MessageBox.Show(ex.Message)
    
        End Try

    Te advierto que la función RunAs no finalizará hasta que finalice la aplicación que has ejecutado, ya que se hace uso de la función API «WaitForSingleObject».

    Recuerda marcar la respuesta como satisfactoria si la misma te ha sido útil.


    Enrique Martínez [MS MVP - VB]

    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.

    sábado, 15 de agosto de 2009 12:12
    Moderador
  • muchas gracias por tu tiempo pero es mas facil hacerles saber, como tu dices ESTE PROGRAMA SOLO FUNCIONA CON RUN AS ADMINISTRATOR    y tendria que ser con el exe que esta en la carpeta bin como ya te dije porque en el exe que genera la publicacion no sale la opcion run as...  y en este codigo se le pide al usuario la contraseña  como escribiste <Cuando desees ejecutar un programa utilizando la cuenta de otro usuario> en cambio la opcion run as.. no la pide (si lo haces dentro del usuario de admin.) pero de todos modos gracias, algun dia me servirá.
    tus respuestas son las mejores

    domingo, 16 de agosto de 2009 3:07
  • "emilios1995" escribió:

    > pero es mas facil hacerles saber, como tu dices ESTE PROGRAMA
    > SOLO FUNCIONA CON RUN AS ADMINISTRATOR  

    Desde luego es lo mejor que puedes hacer, si tu programa se encarga de efectuar operaciones que necesitan privilegios de Administrador.

    > y tendria que ser con el exe que esta en la carpeta bin como ya te dije
    > porque en el exe que genera la publicacion no sale la opcion run as...  

    Cualquier ejecutable tiene la opción «Ejecutar como Administrador», al menos en Windows Vista y en Windows 7, por las características del Control de Cuentas de Usuario. Y la opción «Ejecutar cómo...» en Windows XP, y me imagino que también los tendrán los Windows Servers.

    El ejemplo que te indiqué es para incluirlo en tu aplicación, y desde ésta, poder ejecutar otras aplicaciones que necesiten privilegios de Administrador, de ahí que tengas que conocer el contexto de seguridad de la cuenta del usuario que ejecuta tu aplicación, para poder suplantar la cuenta de otro usuario con permisos administrativos.

    Si a la función CreateProcessWithLogonW le pasas las credenciales de un usuario Administrador, todos los procesos y subprocesos que se ejecuten desde la misma (la aplicación que le has indicado que se ejecute), se harán bajo el contexto de seguridad de la cuenta de usuario pasada a la función API.

    Pero repito que, si no tienes soltura con los temas de seguridad y de las funciones de la API de Windows, mejor será que no te compliques la vida, y diseñes tu aplicación para que sean las cuentas de Administrador la que puedan ejecutarla. Al fin y al cabo, ¿para qué quiere un usuario con una cuenta normal y corriente, ejecutar programas administrativos o de mantenimiento del PC?



    Enrique Martínez [MS MVP - VB]
    domingo, 16 de agosto de 2009 6:13
    Moderador
  • Te equivocas, el CreateProcessWithLogonW sí ejecuta un proceso con otras credenciales, pero no con elevación de privilegios (siempre y cuando el programa que lo lanze haya sido ejecutado COMO ADMINISTRADOR). Creo que os haceis un poco de lío. No es lo mismo ejecutar con un usuario (aunque esté en el grupo de administradores y pueda ser administrador) que ejecutar un proceso con Elevación de privilegios de Administrador.

    Lo que creo que se quiere obtener es, desde un programa que no ha sido ejecutado con privilegios de administrador, poder ejecutar otro programa con privilegios de administrador (suministrándole las credenciales de un usuario administrador, claro). Eso no he podido resolverlo y creo que no se puede. Todo lo más que he podido es ejecutar un proceso con el 'verb=runas' sin suministrarle credenciales y entonces sí, te pregunta por credenciales y ejecutar con elevación de permisos.  ¿alguien sabe hacer eso?

    miércoles, 2 de mayo de 2018 8:16