La automatización robótica de procesos (RPA), al igual que los trabajadores humanos, automatiza tareas a través de sistemas de software o hardware que se ejecutan en una variedad de aplicaciones. El software o los robots pueden aprender flujos de trabajo con múltiples pasos y aplicaciones, como obtener formularios recibidos, enviar mensajes de confirmación, verificar la integridad del formulario, archivar formularios en carpetas y actualizar hojas de cálculo con el nombre del formulario y la fecha de espera de envío. El software RPA está diseñado para aliviar a los empleados de la carga de realizar tareas simples y repetitivas.
Asegúrese de que el cliente correspondiente esté instalado en la computadora local y de que se hayan iniciado rpa-client
y rpa-server
.
El sistema actual admite los siguientes clientes:
ID de aplicación | Nombre |
---|---|
chatear | |
wecom | WeChat empresarial |
Tencent QQ | |
timón | tim |
hablar | DingTalk |
alondra | Feishu |
Dado que las tareas deben ser ejecutadas por un usuario específico, debe asegurarse de que el usuario exista antes de ejecutar la tarea.
http://<host>:<port>/users
POST
JSON
Body
Propiedad | Tipo | Requerido | Descripción |
---|---|---|---|
usuarios | Usuario[] | Requerido | Matriz de objetos de usuario. |
└identificación | Cadena | Opcional | Identificación de usuario. Cuando esté vacío, el servidor generará automáticamente una identificación. |
└ID de aplicación | Cadena | Requerido | ID de aplicación asociado. |
└cuenta | Cadena | Requerido | Cuenta de usuario, utilizada para hacer coincidir clientes. |
└ Apodo | Cadena | Opcional | Apodo del usuario, utilizado para mostrar. |
└ nombre real | Cadena | Opcional | El nombre real del usuario se utiliza para su visualización. |
└empresa | Cadena | Opcional | Para su visualización se utiliza el nombre de la empresa a la que pertenece el usuario. |
Tenga en cuenta que
企业微信
no puede obtener directamenteaccount
de la persona que ha iniciado sesión actualmente. Actualmente, el cliente se empareja mediante la combinación de${realname}_${company}
.
Ejemplo de interfaz:
curl -X POST --location " http://localhost:8080/users "
-H " Content-Type: application/json "
-d " {
" users " : [
{
" id " : " uid " ,
" appId " : " wechat " ,
" account " : " account " ,
" nickname " : " nickname "
}
]
} "
insert into user (id, app_id, account, nickname, realname, company, status, created_time, updated_time)
values ( ' uid ' , ' wechat ' , ' account ' , ' nickname ' , ' realname ' , ' company ' , 1 , now(), null );
http://<host>:<port>/tasks
POST
JSON
Body
Propiedad | Tipo | Requerido | Descripción |
---|---|---|---|
tareas | Tarea[] | Requerido | Matriz de objetos de tarea. |
└identificación | Cadena | Opcional | ID de tarea. Cuando esté vacío, el servidor generará automáticamente una identificación. |
└ ID de usuario | Cadena | Requerido | ID de usuario asociado. |
└ tipo | Cadena | Requerido | Tipo de tarea, consulte la tabla del diccionario de tipos de tarea. |
└ prioridad | Entero | Opcional | Prioridad de la tarea, cuanto menor sea el valor, mayor será la prioridad. Cuando está vacío, se utiliza la prioridad configurada predeterminada. |
└datos | Cadena | Opcional | Datos de la tarea, en formato de cadena JSON . |
└ horarioHora | FechaHora | Opcional | Hora de ejecución de la tarea, por ejemplo: 2022-01-01 10:00:00 . Si está vacío, se ejecutará inmediatamente. |
Ejemplo:
curl -X PATCH --location " http://localhost:8080/tasks "
-H " Content-Type: application/json "
-d " {
" tasks " : [
{
" id " : " tid " ,
" userId " : " uid " ,
" type " : " login " ,
" priority " : " 0 " ,
" data " : "" ,
" scheduleTime " : " 2022-01-01 10:00:00 " ,
}
]
} "
insert into task (id, user_id, app_id, type, priority, data, status, created_time, updated_time, schedule_time)
values ( ' tid ' , ' uid ' , ' wechat ' , ' login ' , 0 , null , 0 , now(), null , ' 2022-01-01 10:00:00 ' );
El servidor proporciona una página de prueba en tiempo de ejecución que los desarrolladores pueden utilizar para probar tareas sencillas localmente. Abra el navegador y visite http://<host>:<port>/index.html
y luego seleccione el cliente que desea probar.
No se requieren parámetros para iniciar sesión en el cliente
No se requieren parámetros para cerrar sesión en el cliente
Formato de parámetro:
Propiedad | Tipo | Requerido | Descripción |
---|---|---|---|
objetivo | Cadena | Requerido | Enviar objeto. |
mensajes | Mensaje[] | Requerido | Matriz de objetos de mensaje. |
└ tipo | Cadena | Requerido | Tipo de mensaje. |
└ contenido | Cadena | Requerido | Contenido del mensaje, contenido del texto o dirección del archivo. |
Tipo de mensaje:
Código | Nombre | Descripción |
---|---|---|
texto | TEXTO | texto |
imagen | IMAGEN | imagen |
video | VIDEO | video |
archivo | ARCHIVO | documento |
Ejemplo de parámetro:
{
"target" : " friend " ,
"messages" : [
{
"type" : " text " ,
"content" : " message "
},
{
"type" : " image " ,
"content" : " https://rpa.leego.io/image.png "
},
{
"type" : " video " ,
"content" : " https://rpa.leego.io/video.mp4 "
},
{
"type" : " file " ,
"content" : " https://rpa.leego.io/file.zip "
}
]
}
Formato de parámetro:
Propiedad | Tipo | Requerido | Descripción |
---|---|---|---|
objetivo | Cadena | Requerido | Nombre del grupo. |
mensajes | Mensaje[] | Requerido | Matriz de objetos de mensaje. |
└ tipo | Cadena | Requerido | Tipo de mensaje. |
└ contenido | Cadena | Requerido | Contenido del mensaje, contenido del texto o dirección del archivo. |
Tipo de mensaje:
Código | Nombre | Descripción |
---|---|---|
texto | TEXTO | texto |
imagen | IMAGEN | imagen |
video | VIDEO | video |
archivo | ARCHIVO | documento |
mencionar | MENCIONAR | recordar |
Ejemplo de parámetro:
{
"target" : " group " ,
"messages" : [
{
"type" : " text " ,
"content" : " message "
},
{
"type" : " image " ,
"content" : " https://rpa.leego.io/image.png "
},
{
"type" : " video " ,
"content" : " https://rpa.leego.io/video.mp4 "
},
{
"type" : " file " ,
"content" : " https://rpa.leego.io/file.zip "
},
{
"type" : " mention " ,
"content" : " member "
}
]
}
No se requieren parámetros para iniciar sesión en el cliente
No se requieren parámetros para cerrar sesión en el cliente
Formato de parámetro:
Propiedad | Tipo | Requerido | Descripción |
---|---|---|---|
objetivo | Cadena | Requerido | Enviar objeto. |
mensajes | Mensaje[] | Requerido | Matriz de objetos de mensaje. |
└ tipo | Cadena | Requerido | Tipo de mensaje. |
└ contenido | Cadena | Requerido | Contenido del mensaje, contenido del texto o dirección del archivo. |
Tipo de mensaje:
Código | Nombre | Descripción |
---|---|---|
texto | TEXTO | texto |
imagen | IMAGEN | imagen |
video | VIDEO | video |
archivo | ARCHIVO | documento |
Ejemplo de parámetro:
{
"target" : " friend " ,
"messages" : [
{
"type" : " text " ,
"content" : " message "
},
{
"type" : " image " ,
"content" : " https://rpa.leego.io/image.png "
},
{
"type" : " video " ,
"content" : " https://rpa.leego.io/video.mp4 "
},
{
"type" : " file " ,
"content" : " https://rpa.leego.io/file.zip "
}
]
}
Formato de parámetro:
Propiedad | Tipo | Requerido | Descripción |
---|---|---|---|
objetivo | Cadena | Requerido | Nombre del grupo. |
mensajes | Mensaje[] | Requerido | Matriz de objetos de mensaje. |
└ tipo | Cadena | Requerido | Tipo de mensaje. |
└ contenido | Cadena | Requerido | Contenido del mensaje, contenido del texto o dirección del archivo. |
Tipo de mensaje:
Código | Nombre | Descripción |
---|---|---|
texto | TEXTO | texto |
imagen | IMAGEN | imagen |
video | VIDEO | video |
archivo | ARCHIVO | documento |
mencionar | MENCIONAR | recordar |
Ejemplo de parámetro:
{
"target" : " group " ,
"messages" : [
{
"type" : " text " ,
"content" : " message "
},
{
"type" : " image " ,
"content" : " https://rpa.leego.io/image.png "
},
{
"type" : " video " ,
"content" : " https://rpa.leego.io/video.mp4 "
},
{
"type" : " file " ,
"content" : " https://rpa.leego.io/file.zip "
},
{
"type" : " mention " ,
"content" : " member "
}
]
}
Formato de parámetro:
Propiedad | Tipo | Requerido | Descripción |
---|---|---|---|
objetivo | Cadena | Requerido | Nombre del grupo. |
contactos | Contacto[] | Requerido | Conjunto de objetos de contacto. |
└ objetivo | Cadena | Requerido | Número de teléfono móvil o dirección de correo electrónico del usuario. |
└ razón | Cadena | Opcional | Añade notas de contacto. |
Ejemplo de parámetro:
{
"contacts" : [
{ "target" : " phone " },
{ "target" : " email " , "reason" : " reason " }
]
}
Demasiado avanzado para mostrarlo.
Para evitar que el cliente se inicie varias veces, los desarrolladores suelen crear objetos mutex. Un mutex es un mecanismo utilizado en la programación de subprocesos múltiples para proteger los recursos compartidos del acceso de múltiples subprocesos o procesos al mismo tiempo.
HANDLE CreateMutexA (
[in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes,
[in] BOOL bInitialOwner,
[in, optional] LPCSTR lpName
);
[in, optional] lpMutexAttributes
Puntero a una estructura SECURITY_ATTRIBUTES. Si este parámetro es NULL
, los procesos secundarios no pueden heredar el identificador.
El miembro lpSecurityDescriptor
de la estructura especifica el descriptor de seguridad para el nuevo mutex. Si lpMutexAttributes
es NULL
, el mutex obtiene un descriptor de seguridad predeterminado. ACL
en el descriptor de seguridad predeterminado del mutex proviene del token principal o de suplantación del creador.
[in] bInitialOwner
Si este valor es TRUE
y la persona que llama crea el mutex, el hilo que llama toma la propiedad inicial del objeto mutex. De lo contrario, el hilo que llama no toma posesión del bloqueo mutex. Para determinar si la persona que llama creó el mutex, consulte la sección Valores de retorno.
[in, optional] lpName
El nombre del objeto mutex. El nombre está limitado a MAX_PATH
caracteres. Las comparaciones de nombres distinguen entre mayúsculas y minúsculas.
Si lpName
coincide con el nombre de un mutex con nombre existente, esta función solicita acceso MUTEX_ALL_ACCESS
. En este caso, el parámetro bInitialOwner
se ignora porque ya está establecido por el proceso de creación. Si el parámetro lpMutexAttributes
no es NULL, determina si el identificador se puede heredar, pero se ignora su miembro descriptor de seguridad.
Si lpName
es NULL
, el mutex se crea sin nombre.
Si lpName
coincide con el nombre de un evento, semáforo, temporizador de espera, trabajo o objeto de asignación de archivos existente, la función falla y la función GetLastError devuelve ERROR_INVALID_HANDLE
. Esto se debe a que estos objetos comparten el mismo espacio de nombres.
El nombre puede tener un prefijo "global" o "local" para crear explícitamente el objeto en el espacio de nombres global o de sesión. El resto del nombre puede contener cualquier carácter excepto la barra invertida (). Para obtener más información, consulte Espacio de nombres de objetos del kernel. Utilice sesiones de Terminal Services para cambiar rápidamente de usuario. Los nombres de los objetos del kernel deben seguir las pautas descritas para Terminal Services para que las aplicaciones puedan admitir múltiples usuarios.
El objeto se puede crear en un espacio de nombres privado. Para obtener más información, consulte Espacios de nombres de objetos.
Si la función tiene éxito, el valor de retorno es el identificador (Handle) del objeto mutex recién creado.
Si la función falla, el valor de retorno es NULL
. Para obtener información de error ampliada, llame a la función GetLastError.
Si el mutex es un mutex con nombre y el objeto existía antes de que se llamara a esta función, el valor de retorno es un identificador del objeto existente y la función GetLastError devuelve ERROR_ALREADY_EXISTS
.
Process Explorer es una herramienta proporcionada oficialmente por Microsoft para averiguar la información Handle
y DLL
que un proceso ha abierto o cargado.
Página oficial de Process Explorer: https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer
Ejemplo:
Tomando WeChat como ejemplo, primero inicie WeChat, busque el proceso llamado WeChat.exe
en la interfaz principal de Process Explorer y selecciónelo.
Luego busque Handle
con Type
Mutant
y Name
Sessions1BaseNamedObjects_WeChat_App_Instance_Identity_Mutex_Name
en la interfaz Lower Pane
.
Después de hacer clic con el botón derecho Close Handle
para cerrar el identificador, puede iniciar un nuevo proceso.
handles = handler . find_handles ( process_ids = [ 10000 ], handle_names = [ r'Sessions1BaseNamedObjects_WeChat_App_Instance_Identity_Mutex_Name' ])
handler . close_handles ( handles )
Código fuente de referencia: client/handler/handler.py
tscon
Cuando utiliza Escritorio remoto para conectarse a una computadora remota, cerrar Escritorio remoto bloquea la computadora y muestra la pantalla de inicio de sesión. En el modo de bloqueo, la computadora no tiene GUI
, por lo que cualquier prueba GUI
actualmente en ejecución o programada fallará.
Para evitar problemas con las pruebas GUI
, puede utilizar la utilidad tscon
para desconectarse del escritorio remoto. tscon
devuelve el control a la sesión local original en la computadora remota, sin pasar por la pantalla de inicio de sesión. Todos los programas en la computadora remota continúan ejecutándose normalmente, incluidas las pruebas GUI
.
tscon
? tscon
es una herramienta proporcionada por los sistemas Windows que se puede utilizar para conectarse a otra sesión en el servidor Host de sesión de Escritorio remoto.
tscon
? tscon { < sessionID > | < sessionname > } [/dest: < sessionname > ] [/password: < pw > | /password: * ] [/v]
parámetro | describir |
---|---|
<sessionID> | Especifica el ID de la sesión a la que conectarse. Si se utiliza el parámetro opcional /dest:<sessionname> , también se puede especificar el nombre de la sesión actual. |
<sessionname> | Especifique el nombre de la sesión a la que conectarse. |
/dest: <sessionname> | Especifica el nombre de la sesión actual. Cuando se conecte a una nueva sesión, esta sesión se desconectará. También puede utilizar este parámetro para conectar la sesión de otro usuario a una sesión diferente. |
/contraseña: <pw> | Especifique la contraseña del usuario propietario de la sesión a la que conectarse. Esta contraseña es necesaria cuando el usuario que se conecta no es propietario de la sesión. |
/contraseña: * | Solicite la contraseña del usuario propietario de la sesión a la que desea conectarse. |
/v | Muestra información sobre la operación que se está realizando. |
/? | Muestra ayuda en el símbolo del sistema. |
Para desconectarse de un escritorio remoto, ejecute el siguiente comando en la computadora remota (en la ventana Conexión a Escritorio remoto) como administrador, por ejemplo, desde la línea de comando:
%windir% S ystem32 t scon.exe RDP-Tcp# # # NNN /dest:console
Donde RDP-Tcp### NNN
es ID
de la sesión de escritorio remoto actual, como RDP-Tcp#5
. Puede verlo en la columna Sesión en la pestaña Usuarios del Administrador de tareas de Windows .
Verá el mensaje Su sesión de Servicios de Escritorio remoto ha finalizado y el cliente de Escritorio remoto se cerrará. Sin embargo, todos los programas y pruebas en la computadora remota seguirán ejecutándose normalmente.
Consejo: La columna de sesión está oculta de forma predeterminada. Para mostrarlo, haga clic derecho en algún lugar de la fila que muestra CPU, Memoria, etc. y seleccione Sesión en el menú contextual que se abre.
Puede utilizar un archivo por lotes para automatizar el proceso de desconexión. En la computadora remota, haga lo siguiente:
for /f " skip=1 tokens=3 " %%s in ( ' query user %USERNAME% ' ) do (
%windir% S ystem32 t scon.exe %%s /dest:console
)
tscon
mantiene la computadora remota desbloqueada, lo que reduce la seguridad del sistema. Una vez completada la ejecución de prueba, puede bloquear la máquina usando el siguiente comando:
Rundll32.exe user32.dll, LockWorkStation
Si el proceso rdpclip.exe
se está ejecutando en la computadora remota y el portapapeles no está vacío cuando se desconecta de la sesión remota, el proceso rdpclip.exe
puede fallar.
Para evitar este problema, puede finalizar el proceso rdpclip.exe
antes de desconectar la sesión.
Si necesita ampliar las funciones de automatización o ser compatible con clientes de diferentes versiones, puede agregar o editar scripts de tareas en el módulo rpa-client/app.
Los dos métodos siguientes se utilizan principalmente en el proyecto:
pywinauto
Es un módulo de Python para la automatización de la GUI de Microsoft Windows. En el caso más simple, le permite enviar operaciones del mouse y el teclado a los controles y cuadros de diálogo de Windows, pero admite operaciones más complejas, como obtener datos de texto.
prueba de aire
Es un marco de prueba de automatización de UI basado en reconocimiento de imágenes multiplataforma lanzado por NetEase Games. Es adecuado para juegos y aplicaciones. Las plataformas compatibles son Windows, Android e iOS.
Asegúrese de que el sistema operativo que está utilizando sea Windows 7 y superior, y que la versión de Python sea 3.7.0 y superior.
Cabe señalar que la versión actual de airtest depende de pywinauto==0.6.3
y el proyecto actual requiere pywinauto==0.6.8
. Agregue el parámetro --no-deps
al instalar las dependencias o ejecute pip install pywinauto==0.6.8
manualmente. pip install pywinauto==0.6.8
.
git clone https://github.com/yihleego/robotic-process-automation.git
cd robotic-process-automation/rpa-client
pip install --no-deps -r requirements.txt
El archivo de configuración del cliente se encuentra en rpa-client/config.yml y los desarrolladores pueden modificar la configuración de acuerdo con escenarios reales.
Propiedad | Descripción | Por defecto |
---|---|---|
servidor.host | anfitrión del servidor | servidor local |
puerto.servidor | Puerto del servidor | 18888 |
ruta.servidor | Ruta del servidor | /rpa |
servidor.ssl | Si habilitar SSL | FALSO |
tamaño de la aplicación | Número máximo de programas que se pueden ejecutar. | 32 |
<appid> . | Ruta de programa personalizada | Obtener del registro |
airtest.cvstrategy | Algoritmo de reconocimiento de imágenes | [tpl, tamizar, enérgico] |
tiempo de espera de prueba de aire | Algoritmo de reconocimiento de imágenes | 20 segundos |
airtest.timeout-tmp | Algoritmo de reconocimiento de imágenes | 3 segundos |
nivel.de.logging | Nivel de registro | DEPURAR |
formato.de.logging | Formato de registro | Formato predeterminado |
registro.nombredearchivo | Nombre del archivo de registro | ./logs/rpa-client.log |
Simplemente ejecute rpa-client/main.py.
Asegúrese de que la versión de Java que está utilizando sea 17 o superior. El servicio depende de MySQL y Redis cuando se ejecuta. Asegúrese de instalarlos e iniciarlos antes de implementar el servicio.
git clone https://github.com/yihleego/robotic-process-automation.git
cd robotic-process-automation/rpa-server
mvn clean install
Propiedad | Descripción | Por defecto |
---|---|---|
spring.datasource.driver-clase-nombre | Basado en fuentes de datos | com.mysql.cj.jdbc.Driver |
primavera.fuente de datos.url | URL de origen de datos | jdbc:mysql://localhost:3306/rpa |
spring.datasource.nombre de usuario | Nombre de usuario de la fuente de datos | |
primavera.fuente de datos.contraseña | Contraseña de fuente de datos | |
primavera.data.redis.host | anfitrión de Redis | servidor local |
spring.data.redis.port | Puerto Redis | 6379 |
spring.data.redis.contraseña | contraseña de redis | |
spring.data.redis.base de datos | base de datos redis | 0 |
La configuración anterior se puede modificar en el archivo application.properties.
Propiedad | Descripción | Por defecto |
---|---|---|
rpa.websocket.puerto | Puerto de servicio WebSocket | 18888 |
rpa.websocket.ruta | Ruta del servicio WebSocket | /rpa |
rpa.websocket.tiempo de espera inactivo | Tiempo de inactividad del servicio WebSocket | 5m |
rpa.converter.patrón de fecha y hora | Formato de fecha y hora global | aaaa-MM-dd HH:mm:ss |
rpa.converter.patrón de fecha | formato de fecha global | aaaa-MM-dd |
rpa.converter.patrón de tiempo | formato de hora global | HH:mm:ss |
rpa.client.clave-cache | Formato de clave de caché del cliente | rpa:cliente: <appid> : <account> |
rpa.client.cache-tiempo de espera | Tiempo de espera de caché del cliente | 5m |
Consulte RpaProperties para obtener más detalles.
Antes de iniciar el servicio, ejecute el siguiente script en la instancia de MySQL
Simplemente ejecute RpaApplication.java.
$(".btn").click();
Para determinar si una aplicación es compatible con UIA, puede utilizar el software Inspect proporcionado oficialmente por Microsoft, que se puede descargar desde el sitio web oficial o desde este almacén:
En el ejemplo, WeChat usa el modo UiaApp porque está implementado en base a UIA; mientras que Enterprise WeChat usa el modo AirApp, que es similar a que solo hay un Canvas en una página web. Todos los elementos se dibujan y representan mediante código. , por lo que sólo se pueden posicionar mediante reconocimiento de imágenes.
Descargue paquetes redistribuibles de Visual C++ para Visual Studio 2013 https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=40784
Consulte: 2#problema
Este proyecto es solo para referencia de aprendizaje, no lo utilice en un entorno de producción.
Este proyecto está bajo la licencia MIT. Consulte el archivo de LICENCIA para obtener más detalles.