Capturar erros "por fora do EXE"

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Capturar erros "por fora do EXE"

Mensagem por JoséQuintas »

Perguntaram isso tempos atrás, e acabei não respondendo na época.
Basicamente, ao encerrar um programa utilizamos CLS, pra sempre sair com tela limpa.
Ou seja, no uso normal, se o programa não deu erro, termina com tela vazia.

Pra rotina de erros duas opções: EXE separado ou embutido.
No caso do embutido, fiz um BAT assim:

CARREGA.BAT
PROGRAMA.EXE
PROGRAMA.EXE /emailerro

E no programa principal, desvia pra emailerro quando tiver o parâmetro /emailerro.

Então basicamente a rotina de erro é a seguinte:
O programa salva a tela e verifica se tem conteúdo.
Mesmo que o primeiro programa tenha sido encerrado, a tela console com erro continua lá.
Então só precisa que o segundo programa salve a tela.
SImples e prático.
Acaba pegando todo tipo de saída fora do comum, seja o usuário teclando Alt-C, ou erros de linqueditor não interceptados pelo Clipper.
E se estiver vazia, significa que correu tudo bem, e o programa não faria nada.

Obs. Como o prompt pode ser C:\WINDOWS\SYSTEM32>, e isso faz parte do que aparece na suposta tela vazia, é bom considerar como tela vazia um conteúdo menor que 10 ou 20 caracteres.

Pena que só funciona em tela texto/console.
Em Harbour WVT por exemplo, que é tela gráfica, já não dá pra usar.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Capturar erros "por fora do EXE"

Mensagem por Pablo César »

José, na sua mensagem se você colocasse o código fonte exemplificando que é uma solução para Clipper, ainda consideraria que é um assunto para a seção Clipper. Mas como trata-se de apenas um relato de procedimento e ainda visto que a sua indicação pode ser aplicada para outras ferramentas em modo console, por isso movi o tópico para esta seção.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Capturar erros "por fora do EXE"

Mensagem por JoséQuintas »

Desta vez discordo.
Na prática a soluçào nem precisaria ter o fonte em Clipper.
A parte importante é que ao abortar o EXE, existe conteúdo na tela.

Precisaria ter o código Clipper pra ficar no tópico postado?
Pra salvar tela....

SAVE SCREEN TO variavel

Pronto, resolvida a questão do código Clipper.
Com isso, temos a tela com o erro (ou sem ele), em uma variável string.

A partir daí, só analisar a string.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Capturar erros "por fora do EXE"

Mensagem por Pablo César »

Ahhh sim, agora entendi. Nada melhor que mostrar um código que demostra toda uma ideia valendo mais do que mil palavras. Então estou mudando para a seção Clipper, mas antes deixa eu contribuir com a sua ideia.
Obs. Como o prompt pode ser C:\WINDOWS\SYSTEM32>, e isso faz parte do que aparece na suposta tela vazia, é bom considerar como tela vazia um conteúdo menor que 10 ou 20 caracteres.
Poderia remover o path em que aparece, excluindo do conteúdo capturado da tela o CurrentFolder. Em Clipper podemos utilizar a função DIRNAME() da CT.LIB.

Outra coisa que pode ser feito é verificar se houve algum erro, mas precisaria criar um arquivo BAT para que gerencie isso. A utilização do arquivo BAT ao invés do EXE no atalho do Windows, pode ser muito útil inclusive para "forçar" a capturar impressoras, mapear unidade de rede, chamar aplicativo externo para imprimir em impressoras em USB, visualizar arquivos de imagens através de aplicativo externos, enfim. Para este caso o arquivo BAT poderia ser algo assim:

Código: Selecionar todos

@ECHO OFF
PROGRAMA.EXE
IF ERRORLEVEL 1 GOTO ERRO
GOTO SAI
:ERRO
CAPTELA.EXE
MANDMAIL.EXE
:SAI
A tela pode também ser salva em arquivo MEM, desta forma:

Código: Selecionar todos

Vtela:=SaveScreen(00,00,24,79)
Save to Tela all like Vtela
Também pode ser gravado em arquivo texto:

Código: Selecionar todos

Function RM_MVSAVE()
Local i := 0
Local nForLoop := 0
Local b := MAXROW()
Local r := MAXCOL()
Local cScreen := SAVESCREEN(0, 0, b, r)
Local nCellSize := INT( len( Savescreen( 0, 0, 0, 0 ) ) * 2 )
Local nStart := 1
Local nRange := Int( ( ( r + 1 ) * nCellSize ) * 1 )
Local cSubString := ''
Local cOutString := ''

For i := 1 To ( b + 1 )
    cOutString := ''
    cSubString := Substr( cScreen, nStart, nRange )
    For nForLoop := 1 To nRange step nCellSize
        cOutString += F_Tab_Ascii( Substr( cSubString, nForLoop, 1 ) )
    Next
    sAux += ( cOutString ) + CHR(13) + CHR(10)
    nStart += nRange
Next
Return cOutString

Function F_Tab_Ascii( cStr ) // Filtra os caracteres indesejados da tela
Local i := 0
Local cAux := ''

For i := 33 TO 180 // 33 ... 255
    cAux += CHR( i )
Next
If !( cStr $ cAux )
   cStr := ' '
Endif
Return cStr
Também pode gravar parte da tela e ainda imprimir, utilizando as funções CHARODD e SCREENSTR da CT.lib:

Código: Selecionar todos

Function Captura()
Local nColInicial:=2
Local nTamLinha:=60

SET ALTERNATE TO TELA.PRN
SET ALTERNATE ON
?? PADC("Tela capturada em "+DTOC(DATE()),80)
? 
For i=4 TO 20
    ? CharOdd(ScreenStr(i,nColInicial,nTamLinha))
Next
SET ALTERNATE OFF
SET ALTERNATE TO
Copy File("TELA.PRN") TO ("LPT1")
Alert("A tela de erro foi impressa.")
Delete File("C:TELA.PRN")
Return Nil
Bom com certeza podem surgir outras ideias. Mas eu ainda prefiro alterar o ErrorSys que é mais garantido. Pois nele podem serem gravados as variáveis que estão disponíveis na memória. No meu sistema mantenho o nome do usuário e pode ser útil para mais tarde questionar sobre o erro ocorrido. Também podem sere gravados os nomes dos arquivos dbfs em aberto, enfim gravando o arquivo de erro no runtime, facilita a gravação de muitas informações.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Capturar erros "por fora do EXE"

Mensagem por JoséQuintas »

Aí que está:
A idéia é pegar o que não passa pela errorsys.
Com o Blinker5, por exemplo, era comum o programa se fechar sem motivo aparente, e sem passar pela errorsys.

Na rotina de erros eu também pesquisava por mensagens de erro, pra alguma ajuda adicional diretamente pro usuário.

Exemplo:

IF "DOS ERROR 4" $ cTextoTela
? "Esta mensagem se refere a limite de arquivos, verifique CONFIG.SYS ou CONFIG.NT"
ENDIF
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Capturar erros "por fora do EXE"

Mensagem por Jairo Maia »

Olá José e Pablo,

Mas no Clipper, isto não poderia ser resolvido com a declaração de uma EXIT PROCEDURE NOME_DA_PROCEDURE, e colocar este controle nela? O que impede o uso da EXIT PROCEDURE? Não se aplicaria a estes casos?
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Capturar erros "por fora do EXE"

Mensagem por Pablo César »

no Clipper, isto não poderia ser resolvido com a declaração de uma EXIT PROCEDURE NOME_DA_PROCEDURE, e colocar este controle nela?
Sim, Jairo. Bem lembrado ! Só que o colega apresentou outra forma de "capturar" o erro de fora do aplicativo em execução". Apenas outras forma.

Para reforçar o conceito de procedimentos INIT e EXIT:

Uma procedure ou função declarada como INIT PROCEDURE <nome> irá sempre executar na inicialização do programa antes do Main ou do módulo principal. Uma procedure ou função declarada como EXIT PROCEDURE <nome> irá executar logo após a procedure/função terminar.

Procedures/funções INIT são úteis se você tiver variáveis do tipo STATIC na inicialização ​​que não podem ser feitas na linha do programa. Ambas procedures INIT e EXIT são úteis para a instalação generalizada e limpeza no módulo que você quer fazer de forma totalmente independente da chamada do programa.

A INIT FUNCTION e EXIT FUNCTION trabalham da mesma forma que as de PROCEDURE. Embora os seus valores de retorno são ignorados.

O Clipper não faz garantias quanto à ordem de execução de procedimentos de INIT e EXIT. Portanto é bom evitar a criação de mais de uma INIT PROCEDURE ou EXIT PROCEDURE.

Em HMG (e creio que no MIniGui também) não suporta o EXIT PROCEDURE. Isso porque o evento ON RELEASE, já cumpriria essa função.

Mas tanto para Harbour ou xHarbour em modo console possuem os mesmos recursos.

Código: Selecionar todos

Function Main()
SetMode(25,80)
cls
@ 13,10 Say "Pressione qualquer tecla para sair"+Variavel_Nao_Existe
wait
Return Nil


EXIT PROCEDURE Test
@ 15,10 Say "EXIT-Procedure"
wait
Return
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Capturar erros "por fora do EXE"

Mensagem por Jairo Maia »

Olá Pablo,
Pablo César escreveu:EXIT PROCEDURE <nome> irá executar logo após a procedure/função terminar.
Permita-me uma correção que penso que pode gerar confusão de interpretação:

Onde o Pablo escreveu: a procedure/função terminar, leia-se: o aplicativo terminar.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Capturar erros "por fora do EXE"

Mensagem por Pablo César »

Obrigado Jairo, isso ai !
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Responder