En este artículo vamos a crear dos programas. El primero será un programa en consola que cree un archivo en una carpeta protegida como por ejemplo C:\\Windows. El segundo programa será una aplicación de entorno visual que ejecutará nuestro primer programa con permisos de administrador.
El programa que necesita permisos de administrador
Haremos un programa muy sencillo en consola que lo único que hace es crear un archivo de texto llamado prueba.txt en la carpeta C:\\Windows. El código es el siguiente:
Visual C++
Code Gear
C#
#include <stdio.h>
int main()
{
FILE *f = fopen("C:\\Windows\\prueba.txt", "wt");
if (f)
{
fprintf(f, "Hola mundo!!");
fclose(f);
}
return 0;
}
#include <stdio.h>
int main()
{
FILE *f = fopen("C:\\Windows\\prueba.txt", "wt");
if (f)
{
fprintf(f, "Hola mundo!!");
fclose(f);
}
return 0;
}
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace ElevationConsoleCSharp
{
class Program
{
static void Main(string[] args)
{
StreamWriter f = File.CreateText("C:\\Windows\\prueba.txt");
f.WriteLine("Hola mundo!!");
f.Close();
}
}
}
Ahora, intenta ejecutar este programa y verás que o sale una excepción o simplemente no crea el archivo. Esto se debe a que la carpeta de Windows está protegida y no se puede acceder a ella al menos que el programa cuente con permisos de administrador.
Si quieres prueba ejecutando el programa en modo administrador y verás como esta vez no sale la excepción y se crea el archivo en C:\\Windows. Para ejecutar el programa en modo administrador simplemente haz clic derecho sobre el .exe y selecciona "Run as administrator".
El programa que invoca al modo administrador
Crea una aplicación de entorno visual y coloca un botón sobre el formulario.
Agregando el ícono de permisos de administrador al botón
Ahora, es agradable, que en nuestro formulario el botón que va a necesitar permisos de administrador se vea un poco diferente a los otros botones para que así el usuario sepa que pasará cuando presiona el botón. La idea es que nuestro botón se vea algo así:
Para hacer esto, vamos a configurar el evento Load o Create del formulario 1 y colocar el siguiente código:
Visual C++
Code Gear
C#
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
// Cambiar el estilo del boton para que se pueda agregar la imagen
button1->FlatStyle = FlatStyle::System;
// Mandar un mensaje para que se agregue la imagen
::SendMessage((HWND)button1->Handle.ToPointer(), 0x160C, 0, 1);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
// Indicamos que es un botón que necesita permisos
// de administrador
Button1->ElevationRequired = true;
}
// Agregar el API de Windows SendMessage
[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
// Función Form1 Load
private void Form1_Load(object sender, EventArgs e)
{
// Cambiar el estilo del boton para que se pueda agregar la imagen
button1.FlatStyle = FlatStyle.System;
// Mandar un mensaje para que se agregue la imagen
SendMessage((IntPtr)button1.Handle, 0x160C, new IntPtr(0), new IntPtr(1));
}
Como puedes ver, en Code Gear es simplemente cuestión de cambiarle una propiedad. En Visual C++ y C# basta con mandar un mensaje a través del API de Windows con el código 0x160C lo cual le indica a Windows que debe agregar una imagen al emisor del mensaje (en este caso el botón). Además debes tener en cuenta que es necesario cambiar la propiedad FlatStyle del botón al tipo System para que el ícono aparezca correctamente.
Si no sabes como utilizar el SendMessage del API de Windows te recomiendo que leas Cómo funciona el sistema de ventanas en Windows.
Ejecutando el programa en modo administrador
Ahora que ya tenemos nuestro botón listo para funcionar, basta con programar su evento clic. En este evento vamos a ejecutar el programa de consola que creamos en la primera parte al cuál llamé programa1.exe.
Si todavía no sabes como ejecutar un programa con código te recomiendo que leas Abrir aplicaciones externas desde C++.
El código del evento clic es el siguiente:
Visual C++
Code Gear
C#
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
ShellExecute(0, TEXT("runas"), TEXT("programa1.exe"), 0, 0, 0);
}
void __fastcall TForm2::Button1Click(TObject *Sender)
{
ShellExecute(0, TEXT("runas"), TEXT("programa1.exe"), 0, 0, 0);
}
// Agregar el API de Windows ShellExecute
[System.Runtime.InteropServices.DllImport("Shell32.dll", EntryPoint = "ShellExecute")]
public static extern int ShellExecute(IntPtr hWnd, string lpOp, string lpFile, string lParam, string lpDir, int showCmd);
// Click del boton
private void button1_Click(object sender, EventArgs e)
{
ShellExecute(IntPtr.Zero, "runas", "programa1.exe", "", "", 0);
}
En C# no necesitas utilizar ShellExecute. Si quieres puedes usar el Process que se encuentra dentro del namespace System.Diagnostics y colocar el verb del ProcessInfo en "runas". Algo así:
ProcessInfo psi = new ProcessStartInfo(); psi.FileName = "programa1.exe"; psi.Verb = "runas"; Process process = new Process(); process.StartInfo = psi; process.Start();
Como puedes notar, la invocación es exactamente la misma a la de una ejecución normal, con la única diferencia que en lugar de utilizar el verbo "open" utilizo el verbo "runas" para que solicite permisos de administrador.
Ahora prueba ejecutando este programa y al presionar el botón deberías ver una ventana que solicita permisos de administrador como la siguiente:
Si presionas Aceptar, se ejecutará el programa1.exe en modo administrador por lo que la creación del archivo prueba.txt no fallará. Para comprobar que el programa funcionó simplemente ubica el archivo C:\\Windows\\prueba.txt y deberás ver que dice "Hola Mundo!!".
Ten en cuenta, que existen muchas tareas que necesitan permisos de administrador, no solo crear archivos en carpetas protegidas como te he mostrado en este artículo. Prueba realizando otras tareas de administrador y adecúalas a tus necesidades.

Wow muy buen Post
Gracias.
Muy buen tip, ahora con el Windows Vista y el Win 7, se hace necesario este tipo de rutinas con privilegios de administrador. Gracias y te mando un Saludo desde México.
Wow! buen tip, aunque no funciona en wpf :/ solo con win forms.