windows services - Habilitar/deshabilitar Aero de un servicio de Windows
windows-services (2)
Tengo un código para habilitar / deshabilitar el servicio de Windows Aero en Vista, y me gustaría ejecutarlo en un servicio de Windows. El código funciona en una aplicación independiente, pero cuando lo ejecuto desde un Servicio, no ocurre nada. No se arrojan errores o excepciones.
Me doy cuenta de que la ejecución del código en un servicio tiene un alcance diferente al de ejecutar el código en una aplicación, pero en este caso, ¿cómo habilitaría / inhabilitaría Aero del servicio? ¿Esto es posible?
Aquí está el código con el que estoy trabajando:
public static readonly uint DWM_EC_DISABLECOMPOSITION = 0;
public static readonly uint DWM_EC_ENABLECOMPOSITION = 1;
[DllImport("dwmapi.dll", EntryPoint="DwmEnableComposition")]
protected static extern uint Win32DwmEnableComposition(uint uCompositionAction);
public static bool EnableAero()
{
Win32DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
}
Editar:
Resulta que la llamada DwmEnableComposition está devolviendo HRESULT 0x80070018 o ERROR_BAD_LENGTH. Parece un error extraño, ya que el código funciona cuando no se está ejecutando como un servicio.
También traté de cambiar todo al siguiente código, pero obtuve el mismo resultado. Establece la estación de ventana y el escritorio, y parece ser correcto, pero la llamada a DwmEnableComposition produce el mismo error. No he incluido las declaraciones de PInvoke por brevedad.
protected override void OnStop()
{
IntPtr winStation = OpenWindowStation("winsta0", true, 0x10000000 /* GENERIC_ALL */);
if (winStation == null || winStation.ToInt32() == 0)
{
String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
}
if (!SetProcessWindowStation(winStation))
{
String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
}
uint thread = GetCurrentThreadId();
IntPtr hdesk = OpenInputDesktop(0, false, 0x10000000 /* GENERIC_ALL */);
if (hdesk == null || hdesk.ToInt32() == 0)
{
String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
}
if (!SetThreadDesktop(hdesk))
{
String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
}
uint result = Win32DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
if (result != 0)
{
String err = new Win32Exception(Marshal.GetLastWin32Error()).Message;
}
}
No lo sé con certeza, pero quizás deba asociar el proceso de su servicio con el escritorio actual antes de que funcione.
Asegúrese de que su servicio pueda interactuar con el escritorio. Luego use SetThreadDesktop () para configurar el escritorio para el hilo de servicio que pasa en un identificador al escritorio llamado "Predeterminado".
No lo he probado, y no puedo garantizar que funcione. Pero podría ser algo para probar?
Buena suerte :)
Tenía el mismo código de error al crear WPF FlowDocuments a través de un servicio que se ejecuta en Vista de 64 bits. Después de investigar, puedo encontrar esta publicación en Microsoft Connect , que señala que
"... El problema es causado por un problema de interoperabilidad con el DWM ..."
y
"... arreglará el bloqueo de WPF en todos los servicios, incluido IIS7 ..."
Aquí está el enlace directo a las descargas hot-fix; KB 959209
Esto solucionó nuestros problemas con la ejecución de pruebas unitarias a través de CruiseControl.Net (CCNet) ejecutando Vista de 64 bits. Las pruebas están bien cuando no se ejecuta a través de un servicio.