miércoles, 6 de febrero de 2013

Ejecutar programa como administrador en Visual Basic .NET

En ocasiones es necesario ejecutar programas como administrador para poder tener suficientes privilegios.Vamos a ejemplificar esto. Imaginemos que queremos guardar una imagen directamente en la unidad C. Para ello tenemos una aplicación con un Picturebox (el cual tiene una imagen), y un botón con el que guardamos la imagen.

Ejemplo de programa

Hacemos doble clic sobre el botón guardar imagen e incluimos el siguiente código:

Try
   'Creamos un bitmap con la imagen contenida en el Picturebox
   Dim bmp As New Bitmap(PictureBox1.Image)
   'Intentamos guardar la imagen en el directorio C (con nombre "imagen.jpg")
   bmp.Save("C:\imagen.jpg", System.Drawing.Imaging.ImageFormat.Png)
   'Si se guarda correctamente mostramos este messagebox
   MessageBox.Show("Guardado con éxito", ":)", MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch
   'En caso de no guardarse, mostramos este messagebox
   MessageBox.Show("Algo ha ocurrido, no se pudo guardar", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

Ejecutamos el programa y pulsamos en el botón "Guardar imagen" y, sorpresa, no se ha podido guardar.

Error al guardar la imagen

¿A qué se debe esto? Pues muy sencillo, para poder guardar archivos en el directorio C es necesario tener privilegios de administrador. Vamos a ver que esto es realmente verdad. Dentro de nuestra carpeta de la aplicación que hemos creado, accedemos al ejecutable (C:\Users\Usuario\Desktop\EjecutarComoadmin\EjecutarComoadmin\bin\Debug\), y hacemos clic con el botón derecho encima del ejecutable (en mi caso el ejecutable se llama EjecutarComoadmin), le damos a Ejecutar como administrador, pulsamos en el botón guardar y..

Guardado con éxito

Como vemos en la imagen, y era de esperar, se ha guardado correctamente. 
La cuestión ahora es la siguiente, ¿cómo forzar a que me aplicación se ejecute siempre como administrador?
En Visual Studio, entramos en la sección de propiedades del proyecto (My Proyect) y pulsamos en el botón Ver configuración de Windows.

Propiedades del proyecto

Dentro de esta sección, podemos ver un archivo XML con varias opciones para configurar nuestra aplicación, como por ejemplo, forzar que el entorno de mayor compatibilidad sea Windows 7. Lo que nos interesa en esta sección es que podemos cambiar los privilegios de la aplicación y hacer que se tenga que ejecutar como administrador. Para ello, en la parte de requestedPrivileges, tenemos que borrar el nivel de privilegios de la aplicación ( <requestedExecutionLevel level="asInvoker" uiAccess="false" />), y sustuirlos por los privilegios de administrador (<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />). Lo podemos ver en la siguiente imagen.

Privilegios de administrador

Una vez cambiado esto, ejecutamos la aplicación y nos aparece un mensaje que nos pregunta si queremos la que aplicación tenga permisos elevados.

Diálogo con permisos

Pulsamos en el botón Reiniciar con otras credenciales y, ¡funciona!, ya nos deja guardar la imagen.

Guardado con éxito

Además, si volvemos al ejecutable que está dentro de la carpeta del proyecto (C:\Users\Usuario\Desktop\EjecutarComoadmin\EjecutarComoadmin\bin\Debug\), y vemos el icono (EjecutarComoadmin.exe), ya aparece el logo que indica que va a pedir privilegios de administrador.

Ejecutable con privilegios

Por último, lo comprobamos, hacemos doble clic sobre el ejecutable y nos pide privilegios. Pulsamos el botón y se guarda correctamente.

10 comentarios:

  1. Error 1 ClickOnce no admite el nivel de ejecución de solicitudes 'requireAdministrator'. CAF eso me aparece ya lo ejecute como administrador tengo 8.1 ayuda porfa bernardo.rico@hotmail.com

    ResponderEliminar
  2. Estupendo tutorial, pero... como sería en visual basic 6??? imposible?

    ResponderEliminar
  3. Error 1 ClickOnce no admite el nivel de ejecución de solicitudes 'requireAdministrator'

    ResponderEliminar
  4. y ¿cómo se hace esto pero para un programa java?

    ResponderEliminar
  5. Genial!!! y como haria esto para un proyecto de biblioteca de clases (plug-in) que no tiene el archivo app.manifest ??'

    ResponderEliminar
  6. Como podría hacer esta función solo una vez... es decir ,a aplicación inicie normal.... Pero cuando se haga una función... esta reinicie el programa como administrador... y se vuelva a desactivar...

    ResponderEliminar
  7. tengo un problema con un codigo necesito una ayuda , explico lo que quiero es una carga masiva de pdf con un solo excel con miles de datos pero uno por uno a pdf un ejemplo es id 123 nombre juan nacionalidad peruana , id 124 nombre pedro nacionalidad boliviana pero en pdf uno por cada id , lo cual me esta dando problemas por mas que trato buscar el error no lo encuentro , errores posibles que me arrojan son mescla de datos , crea un pdf y el siguiente no lo crea , bueno sin tanto preambulo aqui esta el codigo por favor ayuda lo antes posible por fa

    codigo :

    Try

    For i As Integer = 0 To DataGridView1.Rows.Count - 1
    Dim strNombreArchivo As String = filename
    Dim doc As New Document(PageSize.A4.Rotate(), 10, 10, 10, 10)
    doc = New Document(PageSize.A4.Rotate(), 10, 10, 10, 10)
    strNombreArchivo = filename
    strNombreArchivo = Replace(strNombreArchivo, "xlsx", "pdf")
    strNombreArchivo = strNombreArchivo.Replace("Reporte", ((DataGridView1(0, i).Value).ToString))
    Dim file As New FileStream(strNombreArchivo, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)
    Dim strSubTitulo As String = DataGridView1.Columns(i).HeaderText

    PdfWriter.GetInstance(doc, file)
    doc.Open()
    doc.NewPage()

    datatable.AddCell((DataGridView1(i, 0).Value).ToString)
    'datatable.AddCell(strSubTitulo)
    datatable.HeaderRows = 1
    datatable.DefaultCell.BorderWidth = 1

    For j As Integer = 0 To DataGridView1.Columns.Count - 1

    strSubTitulo = DataGridView1.Columns(0).HeaderText

    datatable.AddCell(strSubTitulo)
    Next
    doc.Add(datatable)
    doc.Close()
    file.Close()
    datatable.Rows.Clear()
    ''filename = ""
    'strNombreArchivo = ""

    Next
    de ante mano muchas gracias por su ayuda
    adios

    ResponderEliminar
  8. Muy útil el tutorial y bien explicado. Gracias.

    ResponderEliminar
  9. Este comentario ha sido eliminado por el autor.

    ResponderEliminar