Fazer o AHK aguardar uma resposta do sistema

Pergunte suas dúvidas de programação em AutoHotkey
RicMic
Posts: 4
Joined: 31 Jul 2018, 13:17

Fazer o AHK aguardar uma resposta do sistema

01 Aug 2018, 11:45

Olá, amiguinhos!

Trabalho com um sistema que não tem tempo de resposta estável aos comandos, podendo variar de instantes até muitos segundos, o que baixa a confiabilidade dos scripts que trabalham com a previsão de tempo de resposta estimada pelo comando "Sleep".

Sei que há uma possibilidade de programar o AHK para "aguardar" uma resposta do sistema, assim como, dependendo do tipo da resposta, executar uma determinada ação.

Trocando em miúdos: preciso fazer que o AHK aguarde a resposta para a próxima ação (diminuindo ou aumentando de acordo com a "velocidade" do sistema no dia), assim como executando determinada ação, correspondente à resposta do sistema, sem ter de ficar fazendo verificações de todas as possibilidades em loop.

Uso um script de reconhecimento de imagem muito bacana (findtext, postado pelo Feiyue), que deu um salto de qualidade nas nossas programações.

Socorro! Alguém dá uma luz?
User avatar
Gio
Posts: 422
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Fazer o AHK aguardar uma resposta do sistema

01 Aug 2018, 15:19

Boa tarde RicMic.

Seja bem-vindo ao fórum da comunidade do AutoHotkey.

A confiabilidade do script, especialmente quando falamos de automação de outros programas, é um dos objetivos que devem ser buscados desde o projeto inicial do script, quando pensamos na ideia geral. Além disso, o grau de conhecimento da linguagem de programação e de programação em geral influencia bastante no resultado final. Portanto, a dica que dou é dedicar algum tempo para estudar, conhecer e testar o máximo possível de comandos e também buscar sempre outras formas de interagir com os programas alvo (rotinas de importação, acesso a bancos de dados, tecnologias próprias de automação como o COM, etc).

No meu caso, já consegui fazer vários scripts com rotinas de automação praticamente 100% confiáveis aqui na empresa. A minha evolução com esses scripts se deu mais ou menos assim:

1. Quando comecei a programar scripts para reduzir o trabalho manual em alguns setores da empresa, eu costumava escrever scripts que clicavam nas coordenadas dos campos dos programas (Click), escreviam neles (Send) e que faziam tudo isso de forma intercalada com pausas (Sleep) de modo a aumentar a chance de o programa alvo ter respondido ao comando anterior da forma que eu esperava (pois quando isso não acontece, tudo acaba virando uma bagunça).

2. Com mais um pouco de tempo, eu passei a utilizar também os comandos que permitem controlar o estado das janelas (WinExist(), WinActivate, WinWaitActive) aliados à loops (Loop, While) e condicionais genéricas ou específicas (If (expression), IfWinActive) que checavam constantemente os estados das janelas antes de prosseguir.

3. Depois, comecei a escrever os scripts para interagir diretamente com os campos das janelas, escrevendo os valores no campos (ControlSetText, ControlSend, ControlClick) e verificando se haviam sido escritos corretamente (ControlGet, ControlGetText) de modo que não fosse mais necessário sequer que a janela estivesse ativa. (Dica: Enviar um sinal de espaço com o ControlSend ativa a maioria dos botões e alguns outros tipos de controles).

4. Passado algum tempo, comecei então a aprender um pouco sobre outras formas de interação entre programas, e vi que muitos programas de escritórios possuem rotinas próprias de importação de arquivos de texto, csv ou xml, de modo que a o método mais confiável passava a ser escrever os arquivos de importação (FileAppend) no layout definido pelo programa alvo e importar por ele. Além disso, alguns programas, como o Excel, possuem tecnologias que permitem programas as ações (como a tecnologia COM), sendo métodos de alta confiabilidade para automação das rotinas.

5. Finalmente, comecei a aprender a trabalhar diretamente com os bancos de dados (utilizando SQL), o que também permite um alto nível de confiabilidade na automação dos programas (utilizando uma função chamada adosql(), escrita por um membro da comunidade, é possível executar queries de dentro do script).

Nem sempre vamos ter acesso ao banco de dados dos programas (pois muitas vezes os desenvolvedores não querem liberar) ou lidar com programas que tenham rotinas de importação, mas se qualquer dos dois casos for possível, prefira eles, pois o nível de confiabilidade aumenta muito. Se não forem possíveis, você pode utilizar os outros comandos para criar redundâncias de checagem em um nível aceitável, de modo que a confiabilidade do script seja maior. Essas checagens podem ser feitas de vários métodos diferentes (por exemplo, lendo o texto inserido nos campos, na janela, o título da janela, verificando se uma janela abriu, verificando o título da janela, etc), portanto, é importante sempre lembrar que pode haver um método mais confiável do que o outro e igualmente válido.

preciso fazer que o AHK aguarde a resposta para a próxima ação


Essa questão do aguardar uma resposta vai depender um pouco de que ação o script está executando naquele momento e de como o programa reage aquela ação. Um comando que ativa uma tela permite o uso do WinWaitActive, e um comando que abre uma tela, permite o uso do WinWait. Da mesma forma, existem as variantes negativas (esperar que uma janela não esteja mais ativa ou que não existe mais). Fora isso, a forma de fazer a checagem é realmente com o uso de loops, onde a rotina interna do loop vai esperar uma mudança na tela ocorrer para terminar o loop (break). Existem muitas formas de checar alterações na janela, como coletar os dados dos campos (ControlGetText) ou o texto das telas (WinGetText) e compará-los até que surja a alteração esperada (enviando novamente o comando se ela demorar muito).

:arrow: Uma dica final é sempre que terminar o script, dedicar um tempo à otimização dele. Isso significa basicamente testar o script exaustivamente e tentar encontrar gargalos de confiabilidade ou tempo de execução, reescrevendo eles sempre que possível (normalmente, quando o script é longo, uma parte dele costuma ficar mais sensível a ocasionar erros do que o restante).
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
RicMic
Posts: 4
Joined: 31 Jul 2018, 13:17

Re: Fazer o AHK aguardar uma resposta do sistema

03 Aug 2018, 09:31

Nossa, meu horizonte expandiu muito com essa introdução. Há pouco superamos a fase dos clicks em coordenadas na tela.

Quando começamos com o reconhecimento de imagens, passamos a fazer scripts para rodar em máquinas diferentes, uma vez que antes tínhamos que ajustar todas as coordenadas da tela para cada terminal em que executaríamos os scripts.

Agora vou começar com o meu script tester a verificar as melhores possibilidades de otimizar a interação com o sistema. Creio que seja viável associar os comandos de espera com o reconhecimento de imagem para as ações de acordo com a resposta.

Mãos à obra!

Se alguém mais tiver experiências com essas frentes de interação entre sistemas, compartilhem! Vai ser um excelente aprendizado! :dance:
User avatar
Gio
Posts: 422
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Fazer o AHK aguardar uma resposta do sistema

03 Aug 2018, 12:07

Outra dica importante é utilizar o Window Spy para encontrar o ClassNN dos controles alvo (quando for programar com ControlSend e ControlSetText). O Window Spy é um script do AutoHotkey que vem junto com o pacote de instalação das versões 1.1+. Para acessá-lo, basta executar qualquer script do AutoHotkey que não termine a execução imediatamente (como por exemplo os que tenham janelas ou hotkeys) e depois clicar com o botão direito do mouse no ícone de H verde que fica na bandeja ao lado inferior-direito da tela (as vezes é preciso clicar na seta para exibir os ícones ocultos). Depois é só selecionar a opção Window Spy.

A janela que se abre é uma janela que fica sempre por cima das outras, e ela basicamente contém informações sobre a janela ativa atual e sobre os controles onde você posicionar o mouse encima. Assim, você pode facilmente descobrir o ClassNN do terceiro campo edit da janela (por exemplo), e usar isso para direcionar um ControlSetText.
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
RicMic
Posts: 4
Joined: 31 Jul 2018, 13:17

Re: Fazer o AHK aguardar uma resposta do sistema

06 Aug 2018, 15:07

Muito obrigado pelas dicas até agora!

Iniciei os testes dos comandos e tenho tido dificuldades.

Estou tentando algumas formas de enviar comandos e interagir com as janelas e campos do meu sistema de trabalho (a partir dos dados levantados pelo WindowSpy), mas não tenho conseguido resultado:

Nossos PCs são bloqueados para muitas funções e não tenho privilégio de administrador. Pode ser esse o problema?

F1::
WinGetActiveTitle, Title
ControlFocus, CampoMascara10, ahk_exe programa.exe
Return

F2::
WinGetActiveTitle, Title
ControlClick, CampoMascara10, ahk_class TMenu
Return

F3::
WinGetActiveTitle, Title
ControlGetFocus, CampoMascara10, ahk_class TMenu ;Focus on the control
Return
User avatar
Gio
Posts: 422
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Fazer o AHK aguardar uma resposta do sistema

06 Aug 2018, 16:29

Boa tarde RicMic.

Os privilégios administrativos podem afetar, mas como você ainda está experimentando com os comandos, o melhor é não presumirmos isso ainda. Não tenho como saber se os dados informados no seu exemplo correspondem aos do seu programa alvo, então vamos fazer o seguinte: vou criar um exemplo que nós dois possamos replicar e quando estivermos certos de que o método está compreendido, movemos para outros programas ok :thumbup:

Primeiro, vamos criar uma GUI própria, que possua um título, alguns campos, uma classe de janela, controles com várias classNNs e etc. Depois vamos verificar como encontrar essas informações no WindowSpy e aí criar hotkeys para interagir com esses controles usando os comandos adequados.


1. Criando a GUI - A gui que vamos criar é bem simples: Ela se chamará "Gui do Barulho" e vai permitir que o usuário insira texto em três campos. O texto do primeiro campo é exibido em uma msgbox com um sinal de erro (vermelho) quando o usuário clicar no botão "Gritar" e o texto do segundo campo é exibido em uma msgbox com um sinal de atenção (amarelo) quando o usuário clicar no botão "berrar". Além disso, tem um texto encima no meio da Gui chamado "Texto Legal". Por fim, o texto do terceiro campo será lido pelo assistente de voz do windows quando você clicar no botão "falar".


Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus




2. Descobrindo as informações - Agora que a Gui já está criada, vamos usar o Window Spy para descobrir o título da janela e o ClassNN dos controles que queremos manipular. Você pode verificar isso nas imagens abaixo: as setas vemelhas representam o título da janela na própria janela e no Window Spy. As setas em verde representam o campo cujo mouse está encima e o corresponde ClassNN na janela do Window Spy.

Texto encima.png
(20.39 KiB) Not downloaded yet


primeiro campo.png
(21.38 KiB) Not downloaded yet


Primeiro botao.png
(22.18 KiB) Not downloaded yet


3. Escrevendo os comandos a partir dos ClassNN - Agora que já temos os dados necessários, vamos escrever os comandos para interação com a janela. Vou colocá-los nas hotkeys F2, F3, F4, F5, F6, F7, F8 e F9. Cada uma fará uma coisa diferente entre alterar o texto do campo, acionar o botão (de 2 formas) ou trocar o texto centralizado. Veja como os parâmetros obtidos são escritos, e lembre-se que a ordem dos parâmetros nos comandos é importante. Veja também os métodos utilizados em cada situação.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Execute o código acima e tecle F2, F3, F4, F5, F6, F7, F8, e F9. Veja o que acontece com a tela em cada caso. Depois, analise como foram escritos os comandos em cada hotkey. Depois, tente reproduzir o método demonstrado, escrevendo alguns dos comandos você mesmo, de modo que eles possam afetar especificamente o terceiro campo e o terceiro botão, que não foram afetados nas hotkeys ainda (exceto F9).

:arrow: OBS: O F9 deve ser usado com o mouse encima de um controle da tela (qualquer controle). Trata-se de um método alternativo para interagir com um controle através do handle (e não do ClassNN).

Uma vez que estiver craque em escrever os comandos para automatizar essa gui própria, ficará mais fácil escrever comandos para automatizar outras GUIs :thumbup:

Dica: Quase sempre tem mais de uma forma de fazer alguma coisa em programação. Quando uma não funciona, devemos sempre procurar suas alternativas (workarounds). O conhecimento que você adquire ao longo dos anos é muito importante aqui, por isso nunca pare de frequentar os fórums e ver o que os outros estão fazendo de inovador. Como exemplo, podemos criar um controle de janela do tipo botão facilmente usando o comando Gui, Add, Button, mas se isso não funcionar, o mesmo também pode ser feito com algumas DllCall()s ou até mesmo de outras formas criativas, como usando um controle do tipo imagem com alguns gatilhos que operem quando o usuário clicar na imagem. Convém lembrar que tudo o que já vimos sendo feito em um computador foi feito através de programação, e nesse sentido, saiba que o AutoHotkey pode fazer quase tudo o que é programável também: desde programas de escritório a jogos 3D com gráficos OpenGl e etc.
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
RicMic
Posts: 4
Joined: 31 Jul 2018, 13:17

Re: Fazer o AHK aguardar uma resposta do sistema

14 Aug 2018, 14:31

Olá novamente!

Após nossa conversa, comecei a fazer testes para aprimorar os scripts e superar a fase do sleep.

Percebi que meu sistema não permite a interação via comandos como "WinWait" ou WinActive", e tb não funciona com comandos do tipo "ControlGetText" e "ControlClick", ou seja, não consigo usar nomes de janelas, nem ClassNN para interagir com meu sistema.

A saída para o impasse foi tentar o reconhecimento de imagens. Capturei partes das telas do sistema e consegui fazer com que o AHK aguarde até que elas apareçam, com o seguinte :

Code: [Select all] [Expand] [Download] (Untitled.ahk)GeSHi © Codebox Plus



A partir daí, uso um localizador de imagem que movimenta o cursor até o campo de preenchimento ou botão para prosseguir. Esse problema parece estar resolvido. :superhappy:

A questão agora é que em algumas fases do trabalho, o sistema responde com janelas de avisos; umas 4 diferentes, que podem ou não aparecer conforme a informação lançada (alguns casos aparece 1, outros podem aparecer até 4 em sequência, alguns não aparece nada e, nas que aparecem mais de 1, a ordem não é necessariamente a mesma). Preciso programar a resposta do AHK com a ação correspondente a cada janela (um botão "ok", um botão "fechar" e coisas do tipo). Eu faria uma busca sequencial das alternativas em loop até a sequência do trabalho retomar o andamento.

Percebi que o comando acima é muito eficiente para as janelas que são esperadas, mas não consegui acertar até agora que ele trabalhe com variações, ou seja, janelas que podem ou não aparecer e, caso não encontre, prossiga com o próximo comando. :headwall:

Code: [Select all] [Expand] [Download] (Untitled.ahk)GeSHi © Codebox Plus



Nos casos em que aparece o tal "recadoamarelo", funcionou tranquilo, mas em alguns casos em que não apareceu, o script travou e ficou procurando a imagem pra sempre.

Será que tem alguma variação de sintaxe mais adequada? :eh:

Return to “Eu preciso de ajuda”

Who is online

Users browsing this forum: No registered users and 0 guests