- Información general
- Automatización de IU
- Aplicaciones y tecnologías automatizadas con UI Automation
- Compatibilidad de proyectos
- UI-ANA-016: Introducir URL para abrir el navegador
- UI-ANA-017: ContinueOnError verdadero
- UI-ANA-018: enumerar actividades de OCR / imagen
- UI-DBP-006: uso del contenedor
- UI-DBP-013: uso incorrecto de la automatización de Excel
- UI-DBP-030: uso de variables prohibidas en selectores
- UI-PRR-001: Simular clic
- UI-PRR-002: Simular tipo
- UI-PRR-003: uso incorrecto de aplicación abierta
- UI-PRR-004: retrasos codificados
- UI-REL-001: Idx grande en selectores
- UI-SEC-004: datos de correo electrónico del selector
- UI-SEC-010: Restricciones de aplicaciones / URL
- UI-USG-011: atributos no permitidos
- UX-SEC-010: restricciones de aplicaciones / URL
- UX-DBP-029: uso no seguro de contraseña
- UI-PST-001: nivel de registro de auditoría en la configuración del proyecto
- Herramienta de migración del navegador de UiPath
- Recorte de región
- Grabadora de Computer Vision
- Activar
- Base de anclaje
- Asociar navegador
- Asociar ventana
- Bloquear entrada de usuario
- Aviso
- Comprobar
- Clic
- Clic en imagen
- Desencadenador de clic de imagen
- Clic en texto OCR
- Clic en el texto
- Desencadenador de clic
- Cerrar aplicación
- Cerrar pestaña
- Cerrar ventana
- Anclaje consciente de contexto
- Copiar texto seleccionado
- Desencadenador de cambio del atributo del elemento
- Elemento existente
- Ámbito del elemento
- Desencadenador de cambio de estado de elemento
- Exportar el árbol de la IU
- Extraer datos estructurados
- Buscar elementos secundarios
- Buscar elemento
- Buscar imagen
- Buscar coincidencias de imágenes
- Buscar texto OCR
- Buscar elemento relativo
- Buscar posición de texto
- Obtener ventana activa
- Obtener antecesor
- Obtener atributo
- Obtener información de atributo
- Obtener a partir del portapapeles
- Obtener texto completo
- Obtener texto OCR
- Obtener contraseña
- Obtener posición
- Obtener elemento de origen
- Obtener texto
- Obtener texto visible
- Volver
- Avanzar
- Ir a inicio
- Google Cloud Vision OCR
- Ocultar ventana
- Resaltar
- Desencadenador de tecla de acceso rápido
- Mantener el puntero
- Mantener el puntero en imagen
- Mantener el puntero sobre texto OCR
- Mantener el puntero en el texto
- Imagen existente
- Indicar en pantalla
- Insertar código .NET
- Inject Js Script
- Invocar método de ActiveX
- Desencadenador de pulsación de tecla
- Cargar imagen
- Maximizar ventana
- Microsoft Azure Computer Vision OCR
- Microsoft OCR
- Microsoft Project Oxford Online OCR
- Minimizar ventana
- Supervisar eventos
- Desencadenador del ratón
- Mover ventana
- Ir a
- Texto OCR existente
- Apariencia en elemento
- Fuga en elemento
- Apariencia en imagen
- Fuga en imagen
- Abrir aplicación
- Abrir navegador
- Actualizar navegador
- Reproducir evento de usuario
- Restaurar ventana
- Guardar imagen
- Seleccionar elemento
- Seleccionar varios elementos
- Enviar tecla de acceso rápido
- Establecer región de recorte
- Establecer foco
- Establecer texto
- Establecer en portapapeles
- Establecer atributo web
- Mostrar ventana
- Iniciar proceso
- Desencadenador del sistema
- Realizar captura
- Tesseract OCR
- Texto existente
- Información sobre herramientas
- Escribir en
- Escribir Texto Seguro
- Utilizar primer plano
- Esperar a atributo
- Esperar a fuga de elemento
- Esperar a fuga de imagen
- Desencadenador de eventos de aplicación
- Marcar/Desmarcar
- Comprobar estado de aplicación
- Comprobar elemento
- Clic
- Clic desencadenador de eventos
- Arrastrar y soltar
- Extraer datos de tabla
- Para cada elemento de interfaz de usuario
- Obtener atributo
- Obtener datos del navegador
- Obtener texto
- Obtener URL
- Ir a URL
- Resaltar
- Mantener el puntero
- Inject Js Script
- Atajos del teclado
- Desencadenador de eventos de pulsación de tecla
- Desplazamiento del ratón
- Navegar por el navegador
- Seleccionar elemento
- Establecer datos del navegador
- Establecer navegador de Runtime
- Establecer texto
- Realizar captura
- Escribir en
- Utilizar Aplicación/Navegador
- Transacción de llamada
- Clic en imagen en pantalla
- Hacer clic en botón de barra de herramientas
- Expandir tabla jerárquica ALV
- Expandir árbol ALV
- Expandir árbol
- Lectura de barra de estado
- Inicio de sesión en SAP
- Inicio de sesión en SAP
- Desencadenador de cambio de atributos de sesión de SAP
- Seleccionar fechas en el calendario
- Seleccionar elemento de menú
- Ámbito de la celda de la tabla
- Transacción de llamada
- Clic en imagen en pantalla
- Hacer clic en botón de barra de herramientas
- Expandir tabla jerárquica ALV
- Expandir árbol ALV
- Expandir árbol
- Lectura de barra de estado
- Inicio de sesión en SAP
- Inicio de sesión en SAP
- Seleccionar fechas en el calendario
- Seleccionar elemento de menú
- Ámbito de la celda de la tabla
- Realizar búsquedas en el navegador y recuperar resultados mediante las API de automatización de IU
- Exploración web
- Buscar imágenes
- Hacer clic en imágenes
- Eventos de desencadenador y supervisor
- Crear y anular archivos
- Páginas HTML: extraer y manipular información
- Manipulación de ventana
- Selección de lista automatizada
- Buscar y manipular elementos de ventana
- Gestionar automatización de texto
- Cargar y procesar imágenes
- Gestionar acciones activadas por el ratón
- Automatizar tiempo de ejecución de aplicación
- Ejecución automática de una aplicación local
- Navegación de explorador
- Automatización web
- Ejemplo de ámbito de desencadenador
- Enable UI Automation support in DevExpress
- Computer Vision Local Server
- Automatización móvil
- Notas relacionadas
- Compatibilidad de proyectos
- Obtener tipos de registro
- Obtener registros
- Obtener origen de la página
- Obtener la orientación del dispositivo
- Obtener identificador de sesión
- Instalar aplicación
- Administrar aplicación actual
- Administrar otras aplicaciones
- Abrir enlace profundo
- Abrir URL
- Conexión de dispositivo móvil
- Deslizamiento direccional
- Patrón de dibujo
- Pase de dedo posicional
- Pulse un botón del hardware
- Establecer orientación del dispositivo
- Realizar captura
- Tomar parte de la captura de pantalla
- Elemento existente
- Ejecutar comando
- Obtener atributo
- Obtener elemento seleccionado
- Obtener texto
- Establecer elemento seleccionado
- Establecer texto
- Deslizamiento
- Pulsar
- Escribir Texto
- Terminal
- Notas relacionadas
- Acerca del paquete de actividades de Terminal
- Compatibilidad de proyectos
- Mejores prácticas
- Buscar texto
- Obtener color de la posición
- Obtener la posición del cursor
- Obtener campo
- Obtener campo en posición
- Obtener área de pantalla
- Obtener texto
- Obtener texto en posición
- Mover cursor
- Mover cursor al texto
- Enviar tecla de control
- Teclas de envío
- Teclas de envío seguras
- Establecer campo
- Configurar campo en posición
- Sesión del terminal
- Esperar texto de campo
- Esperar texto en pantalla
- Esperar texto en posición
Insertar código .NET
UiPath.Core.Activities.InjectDotNetCode
Inyecta código .NET en el subproceso principal de interfaz de usuario de la aplicación de destino. Destinado al uso con aplicaciones .NET UI que no exponen tecnologías de automatización tradicionales o no pueden ser correctamente dirigidas por medios tradicionales.
Común
-
ContinuarEnCasoDeError: especifica si la automatización debe continuar incluso cuando la actividad arroja un error. Este campo solo admite valores Boolean (Verdadero, Falso). El valor predeterminado es Falso. Por lo tanto, si el campo está vacío y se produce un error, se detiene la ejecución del proyecto. Si el valor es Verdadero, la ejecución del proyecto continúa independientemente de cualquier error.
Nota: si se incluye esta actividad en Intentar capturar y el valor de la propiedad ContinuarEnCasoDeError es Verdadero, no se detectará error cuando el proyecto se ejecute. - NombreParaMostrar: el nombre de la actividad para ser mostrado.
Entrada
- Ensamblado: la ruta completa al ensamblado .NET compilado que quieres insertar. Este campo solo admite cadenas y variables
String
. -
Nombre del método: el nombre del método que quieres ejecutar. Solo se admiten métodos estáticos públicos.
Nota: Un tipo no puede contener varios métodos con el mismo nombre. En este caso, se produce un error en el tiempo de ejecución. - Destino.Región de recorte: define el rectángulo de recorte, en píxeles, en relación con el Elemento de IU, en las siguientes direcciones: izquierda, arriba, derecha y abajo. Admite números positivos y negativos.
- ElementoDeDestino : usa la variable ElementoDeIU devuelta por otra actividad. Esta propiedad no se puede utilizar junto con la propiedad Selector. Este campo solo admite variables de Elemento de IU.
- Target.Selector : propiedad de texto utilizada para encontrar un elemento de IU concreto cuando se ejecuta la actividad. En realidad, es un fragmento XML que especifica atributos del elemento GUI que está buscando y de algunos de sus elementos principales.
- Target.TimeoutMS : especifica la cantidad de tiempo (en milisegundos) que se debe esperar a que se ejecute la actividad antes de que se produzca el error
SelectorNotFoundException
. El valor predeterminado es 30 000 milisegundos (30 segundos). -
Destino.EsperaListo : antes de realizar las acciones, espera a que el destino esté listo. Están disponibles las siguientes opciones:
- Ninguno: no espera a que exista nada, excepto el elemento de interfaz de usuario de destino, antes de ejecutar la acción. Por ejemplo, puedes utilizar esta opción si quieres recuperar solo el texto de una página web o hacer clic en un botón concreto, sin tener que esperar a que se carguen todos los elementos de la interfaz de usuario. Ten en cuenta que esto puede tener consecuencias no deseadas si el botón depende de elementos que aún no están cargados, como los scripts.
-
Interactivo / Completo : espera que existan todos los elementos de IU de la aplicación de destino antes de ejecutar la acción.
Para evaluar si una aplicación está en estado Interactivo o Completo, se verifican las siguientes etiquetas:
- Aplicaciones de escritorio: se envía un mensaje
wm_null
para comprobar la existencia de las etiquetas<wnd>
,<ctrl>
,<java>
o<uia>
.Si existen, se ejecuta la actividad. - Aplicaciones web:
- Internet Explorer: la etiqueta
<webctrl>
se utiliza para comprobar si el estado Listo del documento HTML es Completo. Además, el Ocupado tiene que estar en "Falso". - Otros: la etiqueta
<webctrl>
se utiliza para comprobar si el estado Listo del documento HTML está Completo.
- Aplicaciones SAP: primero se verifica la presencia de la etiqueta
<wnd>
, después se utiliza una API específica de SAP para detectar si la sesión está ocupada o no.
- TipoDeNombre: el nombre de la clase pública que contiene el método en ejecución. Este campo solo admite cadenas y variables
String
.
Otros
- Privado : si se selecciona, los valores de variables y argumentos ya no se registran en el nivel Detallado.
Salida
- Resultado: el resultado del método invocado, almacenado en una variable
Object
. Este campo solo admite variablesObject
.
La actividad Inyectar código .NET inyecta código solo en el DominioDeAplicación predeterminado.
Algunas aplicaciones están estructuradas de forma que los elementos a los que puedes necesitar acceder o manipular no se encuentran dentro del DominioDeAplicación predeterminado, por lo que no basta con introducir código en el DominioDeAplicación predeterminado. Por lo tanto, si los elementos de la IU que quieres indicar están ubicados en otro DominioDeAplicación, no estarán disponibles para el código inyectado.
Para solucionarlo, debes modificar el proceso de inyección para apuntar al DominioDeAplicación preciso que contiene los elementos de la IU. Más exactamente, debes inyectar el código de la función que se ejecuta en el DominioDeAplicación predeterminado en todos los DominiosDeAplicación no predeterminados o en el DominioDeAplicación no predeterminado específico que contiene los elementos de la IU que deseas indicar.
MarshalByRefObject
que contenga la función que quieres ejecutar en dominios de aplicación no predeterminados:public class CrossAppDomainRunner : MarshalByRefObject
{
public void Execute(IntPtr controlHandle)
{
// Implementation of the method that will be executed in the target AppDomain
Trace.WriteLine("Sunt in " + AppDomain.CurrentDomain.FriendlyName);
Control foundControl = null;
try
{
foundControl = Control.FromHandle(controlHandle);
}
catch (Exception controlException)
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ An exception occurred while getting the control from handle {controlHandle}. The message is: {controlException.Message}, Win32 Error: {lastWin32Error}");
}
if (foundControl != null)
{
Trace.WriteLine($"+++++ Found control {foundControl.Name} from handle {controlHandle}");
}
else
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ Control NOT found based on handle {controlHandle}, Win32 Error: {lastWin32Error}");
}
}
}
public class CrossAppDomainRunner : MarshalByRefObject
{
public void Execute(IntPtr controlHandle)
{
// Implementation of the method that will be executed in the target AppDomain
Trace.WriteLine("Sunt in " + AppDomain.CurrentDomain.FriendlyName);
Control foundControl = null;
try
{
foundControl = Control.FromHandle(controlHandle);
}
catch (Exception controlException)
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ An exception occurred while getting the control from handle {controlHandle}. The message is: {controlException.Message}, Win32 Error: {lastWin32Error}");
}
if (foundControl != null)
{
Trace.WriteLine($"+++++ Found control {foundControl.Name} from handle {controlHandle}");
}
else
{
int lastWin32Error = Marshal.GetLastWin32Error();
Trace.WriteLine($"+++++ Control NOT found based on handle {controlHandle}, Win32 Error: {lastWin32Error}");
}
}
}
Execute
que recibe un parámetro IntPtr
. Este parámetro contiene el valor del control que está intentando encontrar. En este ejemplo, solo necesitas pasar un parámetro IntPtr
, pero en tu situación particular, puedes añadir tantos parámetros como quieras.
ICorRuntimeHost
desde mscoree
. Para ello, debes declarar esa interfaz:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
namespace mscoree
{
[CompilerGenerated]
[Guid("CB2F6722-AB3A-11D2-9C40-00C04FA30A3E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[TypeIdentifier]
[ComImport]
[CLSCompliant(false)]
public interface ICorRuntimeHost
{
void _VtblGap1_11();
void EnumDomains(out IntPtr enumHandle);
void NextDomain([In] IntPtr enumHandle, [MarshalAs(UnmanagedType.IUnknown)] out object appDomain);
void CloseEnum([In] IntPtr enumHandle);
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
namespace mscoree
{
[CompilerGenerated]
[Guid("CB2F6722-AB3A-11D2-9C40-00C04FA30A3E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[TypeIdentifier]
[ComImport]
[CLSCompliant(false)]
public interface ICorRuntimeHost
{
void _VtblGap1_11();
void EnumDomains(out IntPtr enumHandle);
void NextDomain([In] IntPtr enumHandle, [MarshalAs(UnmanagedType.IUnknown)] out object appDomain);
void CloseEnum([In] IntPtr enumHandle);
}
}
Debes declarar una clase que contenga métodos nativos para inicializar el Modelo de objetos componentes (COM):
public static class NativeMethods
{
[DllImport("ole32.dll")]
public static extern int CoInitializeEx(IntPtr pvReserved, COINIT dwCoInit);
public enum COINIT : uint
{
/// Initializes the thread for multi-threaded object concurrency.
COINIT_MULTITHREADED = 0x0,
/// Initializes the thread for apartment-threaded object concurrency.
COINIT_APARTMENTTHREADED = 0x2,
// ...
}
}
public static class NativeMethods { [DllImport("ole32.dll")] public static extern int CoInitializeEx(IntPtr pvReserved, COINIT dwCoInit); public enum COINIT : uint { /// Inicializa el subproceso para la concurrencia de objetos multiproceso.
COINIT_MULTITHREADED = 0x0, /// Inicializa el subproceso para la concurrencia de objetos subprocesos de apartamento.
COINIT_APARTMENTTHREADED = 0x2, // ... } }
ICorRunttimeHost
:
public static ICorRuntimeHost GetCorRuntimeHost()
{
return (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
public static ICorRuntimeHost GetCorRuntimeHost()
{
return (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
GetControlData
es ejecutada por la actividad Inyectar código .NET en el DominioDeAplicación predeterminado:
public static void GetControlData(Int64 controlHandle, out string response)
{
//initialising COM
NativeMethods.CoInitializeEx(IntPtr.Zero, NativeMethods.COINIT.COINIT_MULTITHREADED);
mscoree.ICorRuntimeHost host = null;
try
{
host = (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
catch (COMException comEx)
{
Trace.WriteLine($"COMException: {comEx.Message}, HRESULT: {comEx.ErrorCode}");
}
catch (Exception ex)
{
// Handle other exceptions
Trace.WriteLine($"Exception: {ex.Message}");
}
IntPtr enumHandle = IntPtr.Zero;
try
{
//now that we have ICorRuntimeHost object we can use it to enumerate the other domains
host.EnumDomains(out enumHandle);
object domain = null;
host.NextDomain(enumHandle, out domain);
while (domain != null)
{
//for each appdomain obtained
AppDomain appDomain = (AppDomain)domain;
//appDomain.BaseDirectory; - you might want to copy your dll
//in the appDomain.BaseDirectory cause otherwise it might not find
//the assembly
ObjectHandle handle = appDomain.CreateInstance(
typeof(CrossAppDomainRunner).Assembly.FullName,
typeof(CrossAppDomainRunner).FullName);
// Unwrap to get the actual object
var runnerProxy = handle.Unwrap();
// Use reflection to call the Execute method
MethodInfo executeMethod = runnerProxy.GetType().GetMethod("Execute", new Type[] { typeof(IntPtr) });
//pass parameters as new object[]
executeMethod.Invoke(runnerProxy, new object[] { new IntPtr(controlHandle) });
//go to next appdomain
host.NextDomain(enumHandle, out domain);
if (domain == null)
break;
}
}
finally
{
if (host != null)
{
if (enumHandle != IntPtr.Zero)
{
host.CloseEnum(enumHandle);
}
Marshal.ReleaseComObject(host);
}
}
response = string.Empty;
}
public static void GetControlData(Int64 controlHandle, out string response)
{
//initialising COM
NativeMethods.CoInitializeEx(IntPtr.Zero, NativeMethods.COINIT.COINIT_MULTITHREADED);
mscoree.ICorRuntimeHost host = null;
try
{
host = (ICorRuntimeHost)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("CB2F6723-AB3A-11D2-9C40-00C04FA30A3E")));
}
catch (COMException comEx)
{
Trace.WriteLine($"COMException: {comEx.Message}, HRESULT: {comEx.ErrorCode}");
}
catch (Exception ex)
{
// Handle other exceptions
Trace.WriteLine($"Exception: {ex.Message}");
}
IntPtr enumHandle = IntPtr.Zero;
try
{
//now that we have ICorRuntimeHost object we can use it to enumerate the other domains
host.EnumDomains(out enumHandle);
object domain = null;
host.NextDomain(enumHandle, out domain);
while (domain != null)
{
//for each appdomain obtained
AppDomain appDomain = (AppDomain)domain;
//appDomain.BaseDirectory; - you might want to copy your dll
//in the appDomain.BaseDirectory cause otherwise it might not find
//the assembly
ObjectHandle handle = appDomain.CreateInstance(
typeof(CrossAppDomainRunner).Assembly.FullName,
typeof(CrossAppDomainRunner).FullName);
// Unwrap to get the actual object
var runnerProxy = handle.Unwrap();
// Use reflection to call the Execute method
MethodInfo executeMethod = runnerProxy.GetType().GetMethod("Execute", new Type[] { typeof(IntPtr) });
//pass parameters as new object[]
executeMethod.Invoke(runnerProxy, new object[] { new IntPtr(controlHandle) });
//go to next appdomain
host.NextDomain(enumHandle, out domain);
if (domain == null)
break;
}
}
finally
{
if (host != null)
{
if (enumHandle != IntPtr.Zero)
{
host.CloseEnum(enumHandle);
}
Marshal.ReleaseComObject(host);
}
}
response = string.Empty;
}
El ejemplo anterior inyecta el código en todos los AppDomains. Una vez que encuentres el DominioDeAplicación donde se encuentran los elementos de la IU que quieres indicar, puedes enumerar todos los DominiosDeAplicación, pero inyectar código solo en el DominioDeAplicación necesario.