.net - tipos - ¿Se puede deshabilitar UI Automation para una aplicación WPF 4.0 completa?
wpf tutorial español (5)
Echa un vistazo a este artículo:
Evitar el acceso de UI Automation a una aplicación
¡Se dice que la UIAccess flag
puede ser capaz de resolver sus problemas!
Chack también este artículo para crear un certificado de confianza:
Problema con manifiesto y uiAccess establecido en verdadero ...
Estamos desarrollando una aplicación WPF 4.0 para uso interno.
En algunos clientes, estamos experimentando enormes problemas de rendimiento debido a la automatización de la interfaz de usuario (estos clientes tienen software instalado como el bolígrafo de servicio de tableta, táctil, ...).
Este es un problema conocido para WPF 4.0, ver por ejemplo:
- Problema de rendimiento de WPF debido a la automatización de la interfaz de usuario
- Problema de automatización de la interfaz de usuario de WPF
Hemos podido reproducir este problema en una máquina con especificaciones muy limitadas. Abrir una ventana WPF en esta máquina toma:
- 00:00:02 - sin ningún software de activación de automatización de UI instalado
- 00:01:41 - con el software de activación de automatización UI instalado (RoboForm para esta prueba)
- 00:00:09 - con el software de activación de automatización de la interfaz de usuario instalado y la revisión KB2484841 aplicada
Como puede ver, la instalación de la revisión KB2484841 es una gran mejora, pero aún no es tan rápida como la ejecución sin el software de activación de automatización ui instalado.
Además, no tenemos mucho control sobre qué software instalar en los clientes, por lo que es difícil implementar esta solución para todos los clientes.
Por lo tanto, ¿es posible "desactivar" la automatización de la interfaz de usuario para una aplicación WPF completa? Sé que se puede hacer por UserControl, pero ¿es posible para la aplicación en su conjunto?
He probado el código provisto en esta publicación, pero sin éxito.
Gracias por tu tiempo,
Koen
Has probado las siguientes cosas:
El código de automatización se activará solo si hay clientes de automatización (como el lector de pantalla, la información de tabulación en las tabletas, etc.) ejecutándose en la máquina. Así que una forma de salir de esta situación es cerrar cualquiera de esas aplicaciones de cliente de automatización.
Si uno no es factible, entonces una alternativa es, UIElementHelper.InvalidateAutomationAncestors tomará más tiempo solo si el árbol de automatización para la aplicación es escaso (ocurre si se ha desactivado el árbol de automatización de edificios utilizando el par de automatización de ventanas personalizado) y el árbol visual es denso. Otra solución es deshabilitar cualquier código de automatización personalizado y permitir que WPF construya un árbol de automatización completo. Esto debería acelerar UIElementHelper.InvalidateAutomationAncestors también.
Esto es lo que he encontrado con respecto a su problema, también dijeron que están conscientes de este problema e intentarán solucionarlo.
Prueba alguna programación de carga de culto:
WindowInteropHelper helper = new WindowInteropHelper(mainWindow);
AutomationElement mainWindowAutomationElement = AutomationElement.FromHandle(helper.Handle);
Automation.Automation.AddStructureChangedEventHandler(mainWindowAutomationElement, TreeScope.Descendants, AutomationFix);
void AutomationFix(object sender, StructureChangedEventArgs e)
{
AutomationElement element = sender as AutomationElement;
Automation.Condition condition = new PropertyCondition(AutomationElement.NameProperty, "!!");
AutomationElement automationElement = element.FindFirst(TreeScope.Children, condition);
}
Tuvimos el mismo problema con los controles DevExpress . Ningún código de solución nos ayuda. Y supongo que no hay ningún "interruptor" para deshabilitar la automatización de la interfaz de usuario. Pero desde las últimas versiones, DevExpress tiene la clase mágica ClearAutomationEventsHelper que hace algunos trucos. Como entendí, la idea es borrar la propiedad AutomationEvents.Count (a través de Reflection) para los controles que causan problemas. Por ejemplo, llaman a este método en sus controles básicos (desde MeasureOverride), o cada vez que se crea un compañero de automatización.
Si usa DevExpress, esta clase puede ser una bala de plata para su proyecto. Pudimos evitar por completo los efectos secundarios de los problemas de automatización de la interfaz de usuario en nuestros proyectos WPF 4.0 y los clientes estaban realmente contentos.
Nos topamos con el mismo problema que se menciona en la pregunta, donde un cliente de automatización de UI estaba afectando el rendimiento de nuestra aplicación WPF
.
Después de probar todas las soluciones y soluciones, finalmente encontramos una solución. Cada control de UI tiene un objeto AutomationPeer
que expone las propiedades del control actual y sus controles secundarios. El cliente de automatización de la interfaz de usuario utiliza estos objetos AutomationPeer
para obtener la información sobre los controles de la interfaz de usuario. Hay una clase de pares de automatización incorporada para la mayoría de los controles de UI en WPF
y también podemos crear una clase de pares personalizada.
La siguiente es una clase personalizada de pares de automatización. Tenga en cuenta que en el método GetChildrenCore
, está devolviendo una lista vacía en lugar de la lista de controles secundarios reales.
public class CustomWindowAutomationPeer : FrameworkElementAutomationPeer
{
public CustomWindowAutomationPeer(FrameworkElement owner)
: base(owner) { }
protected override string GetNameCore()
{
return "CustomWindowAutomationPeer";
}
protected override AutomationControlType GetAutomationControlTypeCore()
{
return AutomationControlType.Window;
}
protected override List<AutomationPeer> GetChildrenCore()
{
return new List<AutomationPeer>();
}
}
Luego, en su ventana principal, anule el método OnCreateAutomationPeer
:
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
return new CustomWindowAutomationPeer(this);
}
Ahora, cuando el cliente de automatización de la interfaz de usuario intenta obtener los controles secundarios de la ventana principal, recupera una lista vacía y, por lo tanto, no puede recorrer el resto de los controles.
Consulte este artículo de MSDN para más detalles.