Reiniciar Windows desde .NET

Published 22/5/2007 17:29 | Rafael Ontivero

En anteriores entradas comenté que explicaría cómo reiniciar Windows desde un programa hecho en .NET. Hasta donde yo sé el .NET Framework no tiene un API para cerrar la sesión actual o para reiniciar el sistema, así que tenemos que hacer las llamadas oportunas al código nativo.

En Win32 hay dos funciones para realizar la tarea, la original, ExitWindows y otra más moderna y que permite más cosas, ExitWindowsEx.

Pero si probamos a llamarlas directamente nos damos cuenta de que Windows nos ignora por completo y no hace nada. Eso se debe a que un programa no tiene los privilegios necesarios para realizar tal tarea, por lo que es necesario que primero se los asigne antes de llamar al método de reinicio.

El privilegio que necesitamos es SE_SHUTDOWN_NAME para poder reiniciar el propio ordenador o para cerrar la sesión activa. Y ya que vamos a necesitar acceso al código nativo, lo vamos a hacer desde un método que hemos llamado MySystemShutdown y que recibe un valor UINT (equivalente a un UInt32 del .NET) con la acción que queramos realizar.

Los valores posibles para el parámetro son:

Nombre Macro

Valor numérico

Descripción

EWX_LOGOFF

0

Cierra la sesión actual

EWX_POWEROFF

0x00000008

Apaga el ordenador.

EWX_REBOOT

0x00000002

Reinicia el ordenador.

EWX_RESTARTAPPS

0x00000040

Reinicia el ordenador abriendo todas las aplicaciones que hubiera registradas para hacerlo.

 

Aquellos que estén utilizando C++/CLI deben tener dichas macros habilitadas si han incluido Windows.h. Los programadores de C# pueden utilizar los valores numéricos (aparte de tener que traducir la rutina o meterla en una clase y crearse un ensamblado).

Y, finalmente, el código (que está sacado de la MSDN con ligeras modificaciones):

BOOL MySystemShutdown(UINT action)

{

   HANDLE hToken;

   TOKEN_PRIVILEGES tkp;

 

   // Get a token for this process.

   if (!OpenProcessToken(GetCurrentProcess(),

        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))

      return( FALSE );

 

   // Get the LUID for the shutdown privilege.  

   LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,

        &tkp.Privileges[0].Luid);

 

   tkp.PrivilegeCount = 1;  // one privilege to set   

   tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

 

   // Get the shutdown privilege for this process.  

   AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

        (PTOKEN_PRIVILEGES)NULL, 0);

 

   if (GetLastError() != ERROR_SUCCESS)

      return FALSE;

 

   // Shut down the system and force all applications to close.  

   if (!ExitWindowsEx(action | EWX_FORCE,

               SHTDN_REASON_MAJOR_OPERATINGSYSTEM |

               SHTDN_REASON_MINOR_UPGRADE |

               SHTDN_REASON_FLAG_PLANNED))

      return FALSE;

 

   return TRUE;

}

 

Archivado en: ,,,
Comparte este post:

Comentarios

# Rafael Ontivero said on January 9, 2008 5:38 PM:

Baja esto: rfog.cmact.com/.../zxShutdown.zip y mira en el siguiente hilo: groups.google.com/.../52dd25d8843e6973

Hay un mensaje en el que explico cómo hacerlo.

A ver si pongo una entrada completa sobre el tema.

# fresa said on October 14, 2008 12:55 AM:

hay nooooooooo!!

porq no saben nada

ballanse a unas clases de computation no???

iia es hora de que se actualicen!!