Problema com Run/RunWait em certas situações

Tire suas dúvidas sobre programação em AutoHotkey

Moderator: Gio

User avatar
DevWithCoffee
Posts: 54
Joined: 13 Oct 2020, 12:16

Problema com Run/RunWait em certas situações

13 Oct 2020, 12:44

Eu quero iniciar um BatchScript ou comando no prompt minimizado, porém não funciona de nenhuma maneira.

As maneiras que eu tentei.

Code: Select all

RunWait, , MyScript.bat, , Min

Code: Select all

RunWait, , %ComSpec% /c start /min MyScript.bat, , Min
Isso não acontece clicando diretamente no arquivo AHK, mas se eu tiver com algum programa feito pra rodar em tela cheia, como um BatchScript, Clipper ou qualquer programa em tela cheia perde o foco e mostra a tela que estiver aberta, seja Desktop ou a pasta onde foi aberto.

Não sei se tem relação, mas eu notei que alguns programas, mesmo sendo visual acontece o mesmo, como a calculadora que não permite maximizar, mas permite minimizar não funciona, abre pelo padrão:

Code: Select all

RunWait, , calc, , Min
Eu consegui corrigir o problema criando um atalho do %ComSpec%, e forçando pelas propriedades que ele inicie minimizado.

Code: Select all

RunWait, , prompt.lnk /c start /min MyScript.bat, , Min
Mas isso é gambiarra demais, por que pode ser um erro meu ou da versão do código Master do AHK.

Meu OS: Windows XP 32
Eu não sei se é problema com versão do compilador.
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Problema com Run/RunWait em certas situações

14 Oct 2020, 09:49

Bom dia DevWithCoffee.

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

Alguma razão para não executar o prompt com o parâmetro Hide no lugar do minimizar? Você pode fazer isso se não precisar que o prompt do batch esteja visível na barra de tarefas durante o processo.

Exemplo de uso do parâmetro hide: No código abaixo, o processo de ping através da hotkey F2 é visível, mas o da hotkey F3 não é.

Code: Select all

F2::
Run, %ComSpec% /c ping 192.168.0.1
Return


F3::
Run, %ComSpec% /c ping 192.168.0.1,, HIDE
Return

:arrow: Mas se você precisar mesmo que a janela esteja visível na barra de tarefas, tem outras opções. As vezes, o parâmetro /min está funcionando, mas os programas ou o Sistema Operacional podem apresentar comportamentos próprios de ativação/inativação de janelas durante sua execução. Caso o prompt esteja maximizando a janela sozinho, você também pode usar o comando WinMinimize logo em seguida para minimizar automaticamente a janela. Para fazer isso efetivamente, simplesmente faça o script esperar a janela existir ou estar ativa através de WinWait e/ou WinWaitActive.

Exemplo: No código abaixo, ao pressionar F2, o script abre a tela do prompt para rodar o comando ping, e depois, assim que vê que a tela foi efetivamente aberta, minimiza ela automaticamente.

Code: Select all

F2::
Run, %ComSpec% /c ping 192.168.0.1
WinWaitActive, ahk_class ConsoleWindowClass
WinMinimize,  ahk_class ConsoleWindowClass
Return
Perceba que no código acima, não foi utilizado o parâmetro hide, e portanto, a janela continua visível na barra de ferramentas.

Mas isso é gambiarra demais, por que pode ser um erro meu ou da versão do código Master do AHK.

Na programação o ato de usar outra forma de fazer a mesma coisa é extremamente comum, mas é mais comumente chamado de workaround. O nome "gambiarra" carrega uma pecha de algo que não tem durabilidade, mas os workarounds não costumam ser assim. O programador tem a competência de analisar a integridade final do código e decidir se está bom, e se estiver, saber que ele nunca vai quebrar. Sendo assim, se funcionou da forma esperada e você viu que não tem problema em usar, tudo bem continuar usando :beer:

Meu OS: Windows XP 32

Bom, acredito que nessa altura do campeonato você deve ter uma boa razão para estar usando um Windows tão antigo. Isso sem dúvida pode trazer muitos problemas de compatibilidade, pois os programas não são mais desenvolvidos para o Windows XP há muito tempo. De qualquer forma, no caso do AutoHotkey, creio que apenas algum comando ou outro que eventualmente não funcionaria nessa versão. Se não funcionar, é só tentar um workaround.
User avatar
DevWithCoffee
Posts: 54
Joined: 13 Oct 2020, 12:16

Re: Problema com Run/RunWait em certas situações

14 Oct 2020, 22:38

Gio wrote:Seja bem-vindo ao fórum da comunidade do AutoHotkey.
Obrigado.
Alguma razão para não executar o prompt com o parâmetro Hide no lugar do minimizar? Você pode fazer isso se não precisar que o prompt do batch esteja visível na barra de tarefas durante o processo.
Eu usava, acontecia o mesmo problema que usando Min.
Mas se você precisar mesmo que a janela esteja visível na barra de tarefas, tem outras opções. As vezes, o parâmetro /min está funcionando, mas os programas ou o Sistema Operacional podem apresentar comportamentos próprios de ativação/inativação de janelas durante sua execução.
O estranho que definindo como "minimizado" pelo atalho que eu criei o problema não acontece, então deu à entender que o Run invoca a tela de comando "em foco", ao que entendi isso acontece apenas em "FullScreen".
Exemplo: No código abaixo, ao pressionar F2, o script abre a tela do prompt para rodar o comando ping, e depois, assim que vê que a tela foi efetivamente aberta, minimiza ela automaticamente.

Code: Select all

F2::
Run, %ComSpec% /c ping 192.168.0.1
WinWaitActive, ahk_class ConsoleWindowClass
WinMinimize,  ahk_class ConsoleWindowClass
Return
Eu já fiz algo semelhante à este processo, ao trocar a tela gera um intervalo de segundos do vídeo mudando de Windows pra DOS e vice-versa que atrapalha o usuário se esteve estiver digitando, o que acontece.
Mas isso é gambiarra demais, por que pode ser um erro meu ou da versão do código Master do AHK.
Na programação o ato de usar outra forma de fazer a mesma coisa é extremamente comum, mas é mais comumente chamado de workaround. O nome "gambiarra" carrega uma pecha de algo que não tem durabilidade, mas os workarounds não costumam ser assim.
Foi a única maneira que achei de expressar meu ponto de vista com a solução que eu arrumei.
Sendo assim, se funcionou da forma esperada e você viu que não tem problema em usar, tudo bem continuar usando :beer:
Neste momento é o que estou fazendo.
Meu OS: Windows XP 32
O sistema do cliente funciona nesta plataforma, a ideia foi preservar funcionando devido à grande carga de dados de décadas de operação, eu demorei meses pra descobrir o banco de dados do sistema, e mesmo assim não achei maneira de converter, não existe documentação em português ou inglês fácil pra essas plataformas, também, aprender uma linguagem de programação obsoleta tomaria mais tempo ainda. Diferente do AHK que eu me familiarizei de primeira.

Antes eu usava VBS pra fazer o que a linha de comando não podia, mas mudei pro AHK por coisas como está:
Spoiler
Além de tudo, escrevo muito menos e tive mais resultado.

Vale lembrar que eu não deixo nenhum código AHK aberto pros clientes, claro, pra qualquer um que mexe com isso é fácil extrair o código por 7-Zip ou mesmo Notepad++, mas pro cliente não.

Bem, de qualquer maneira, vou revisar o código e efetuar outras simulações sem precisar fazer isso em uma das estações (ponto de acesso do servidor) e vendo que não tem saída vai ficar funcionando pelo "atalho" que eu criei:
Attachments
ComSpec.PNG
ComSpec.PNG (9.45 KiB) Viewed 938 times
Last edited by DevWithCoffee on 16 Oct 2020, 00:12, edited 1 time in total.
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Problema com Run/RunWait em certas situações

15 Oct 2020, 10:57

Certo, bom, se nenhuma das opções do comando Run não está funcionando a contento, creio que vamos ter que procurar um workaround. Felizmente a programação Windows parece ser farta de opções nesse sentido.

Se entendi direito, o problema é a tela do console abrindo por uma fração de segundo certo? Tem uma função antiga escrita por alguns usuários (Sean, nfl, cyruz) que pode executar linhas de comando de forma oculta (e que retorna o texto do console caso queira consultar).

Aqui vai um exemplo: Execute o código abaixo e pressione a tecla F4 para fazer o comando do console executar de maneira oculta através de DllCall()s. (OBS: no código abaixo a msgbox com o resultado do ping está sendo exibida somente para ver que foi executado, você não precisa dessa linha, pode deixar o comando executar oculto mesmo. Removendo a linha do msgbox, verá que o foco da janela atual não será perdido após a execução da função, nem mesmo por uma fração de segundo).

Code: Select all

F2::
Run, %ComSpec% /c ping 192.168.0.1,, HIDE
Return


F3::
Run, %ComSpec% /c ping 192.168.0.1
WinWaitActive, ahk_class ConsoleWindowClass
WinMinimize,  ahk_class ConsoleWindowClass
Return

f4::
Var := StdoutToVar_CreateProcess("ping 192.168.0.1")
msgbox % Var
Return




; ----------------------------------------------------------------------------------------------------------------------
; Function .....: StdoutToVar_CreateProcess
; Description ..: Runs a command line program and returns its output.
; Parameters ...: sCmd      - Commandline to execute.
; ..............: sEncoding - Encoding used by the target process. Look at StrGet() for possible values.
; ..............: sDir      - Working directory.
; ..............: nExitCode - Process exit code, receive it as a byref parameter.
; Return .......: Command output as a string on success, empty string on error.
; AHK Version ..: AHK_L x32/64 Unicode/ANSI
; Author .......: Sean (http://goo.gl/o3VCO8), modified by nfl and by Cyruz
; License ......: WTFPL - http://www.wtfpl.net/txt/copying/
; Changelog ....: Feb. 20, 2007 - Sean version.
; ..............: Sep. 21, 2011 - nfl version.
; ..............: Nov. 27, 2013 - Cyruz version (code refactored and exit code).
; ..............: Mar. 09, 2014 - Removed input, doesn't seem reliable. Some code improvements.
; ..............: Mar. 16, 2014 - Added encoding parameter as pointed out by lexikos.
; ..............: Jun. 02, 2014 - Corrected exit code error.
; ..............: Nov. 02, 2016 - Fixed blocking behavior due to ReadFile thanks to PeekNamedPipe.
; ----------------------------------------------------------------------------------------------------------------------
StdoutToVar_CreateProcess(sCmd, sEncoding:="CP0", sDir:="", ByRef nExitCode:=0) {
    DllCall( "CreatePipe",           PtrP,hStdOutRd, PtrP,hStdOutWr, Ptr,0, UInt,0 )
    DllCall( "SetHandleInformation", Ptr,hStdOutWr, UInt,1, UInt,1                 )

            VarSetCapacity( pi, (A_PtrSize == 4) ? 16 : 24,  0 )
    siSz := VarSetCapacity( si, (A_PtrSize == 4) ? 68 : 104, 0 )
    NumPut( siSz,      si,  0,                          "UInt" )
    NumPut( 0x100,     si,  (A_PtrSize == 4) ? 44 : 60, "UInt" )
    NumPut( hStdOutWr, si,  (A_PtrSize == 4) ? 60 : 88, "Ptr"  )
    NumPut( hStdOutWr, si,  (A_PtrSize == 4) ? 64 : 96, "Ptr"  )

    If ( !DllCall( "CreateProcess", Ptr,0, Ptr,&sCmd, Ptr,0, Ptr,0, Int,True, UInt,0x08000000
                                  , Ptr,0, Ptr,sDir?&sDir:0, Ptr,&si, Ptr,&pi ) )
        Return ""
      , DllCall( "CloseHandle", Ptr,hStdOutWr )
      , DllCall( "CloseHandle", Ptr,hStdOutRd )

    DllCall( "CloseHandle", Ptr,hStdOutWr ) ; The write pipe must be closed before reading the stdout.
    While ( 1 )
    { ; Before reading, we check if the pipe has been written to, so we avoid freezings.
        If ( !DllCall( "PeekNamedPipe", Ptr,hStdOutRd, Ptr,0, UInt,0, Ptr,0, UIntP,nTot, Ptr,0 ) )
            Break
        If ( !nTot )
        { ; If the pipe buffer is empty, sleep and continue checking.
            Sleep, 100
            Continue
        } ; Pipe buffer is not empty, so we can read it.
        VarSetCapacity(sTemp, nTot+1)
        DllCall( "ReadFile", Ptr,hStdOutRd, Ptr,&sTemp, UInt,nTot, PtrP,nSize, Ptr,0 )
        sOutput .= StrGet(&sTemp, nSize, sEncoding)
    }
    
    ; * SKAN has managed the exit code through SetLastError.
    DllCall( "GetExitCodeProcess", Ptr,NumGet(pi,0), UIntP,nExitCode )
    DllCall( "CloseHandle",        Ptr,NumGet(pi,0)                  )
    DllCall( "CloseHandle",        Ptr,NumGet(pi,A_PtrSize)          )
    DllCall( "CloseHandle",        Ptr,hStdOutRd                     )
    Return sOutput
}
Return
Créditos e referências: https://www.autohotkey.com/boards/viewtopic.php?t=791
User avatar
DevWithCoffee
Posts: 54
Joined: 13 Oct 2020, 12:16

Re: Problema com Run/RunWait em certas situações

19 Oct 2020, 20:27

Desculpe, não tive tempo de analisar, também peço desculpa, fazendo um teste simulado notei que a Option HIDE está trabalhando corretamente, somente a MIN que não.

Eu acabei criando uma simulação do que acontece, se houver interesse:
Código
Acredito que pode fechar o tópico.

Return to “Ajuda e Suporte Geral”

Who is online

Users browsing this forum: No registered users and 47 guests