Página 1 de 1

Reiniciar sistema que saiu do ar brutalmente

Enviado: 03 Fev 2016 13:31
por rochinha
Amiguinhos,

Vendo uma necessidade antiga precisando de solução, sai a caça e consegui esboçar a seguinte solução:

CASO:
Seu sistema esta rodando e puuuuum, sai brutalmente, sem aviso ou com erro de variável, falta de campo, arquivo corrompido, qualquer forma que não seja pela saida normal onde seu sistema alerta o usuário: "...Tem certeza mesmo que deseja sair do sistema?..."

Então desenvolvi o seguinte código para vocês entenderem e implementar:

CÓDIGO:

Código: Selecionar todos

////////////////////////////////////////////////////////////////////////////
//
//         Autor: Jose Carlos da Rocha                                                                                              
//          Data: 03/02/2016
//         Email: irochinha@hotmail.com.br
//     Linguagem: xBase / Fivewin
//   Plataformas: DOS, Windows
// Requerimentos: Harbour/xHarbour
//
////////////////////////////////////////////////////////////////////////////

#include "fivewin.ch"

function main()

   local oWnd
   local oBtn1, oBtn2, oBtn3
   
   // Usei estas funções para trazer o nome sem extensão do aplicativo que esta rodando
   cTaskName := StrTran( upper(cFileName(GetModuleFileName(GetInstance()))), ".EXE", "" )

   // Uso esta funçao para obter a linha de comando completa de chamada, exemplo: c:\diretorio\sistema.exe
   cCMDRun   := GetModuleFileName(GetInstance())

   // Previne multiplas instancias
   SOSFile   := cTaskName+".sos"
   if file(SOSFile)
      fErase(SOSFile) // Tenta eliminar o arquivo de controle
      if fError() <> 0
         //if ! MsgYesNo( "O sistema ja se encontra aberto.Veja o icone ao lado do relogio", "Multiplas instancias" )
            quit
         //endif
      endif
   endif
   SOSHandle := fCreate(SOSFile) // Cria o arquivo de controle
   SOSHandle := fOpen(SOSFile,1) // Abre travando o arquivo de controle
   
   SET _3DLOOK ON
   
   // Cria a tarefa AntiStealth
   EXETaskCreate( ;
                  cTaskName, ; // Nome da tarefa usando o nome do aplicativo ativo
                  GetModuleFileName(GetInstance()) ; // Caminho completo do aplicativo
                  )
   
   DEFINE WINDOW oWnd TITLE "Test Schedule Task" // FROM 0, 0 TO 400, 300
          DEFINE BUTTONBAR oWBar _3D SIZE 33, 33 OF oWnd
          DEFINE BUTTON oBtn1 OF oWBar ;
                 TOOLTIP "Forca a Saida" ;
                 ACTION oWnd:End()
          DEFINE BUTTON oBtn2 OF oWBar ;
                 TOOLTIP "Saida Normal" ; // Se o usuario saiu normalmente, apenas desabilita a tarefa
                 ACTION ( EXETaskDisable( cTaskName ), oWnd:End() )
          DEFINE BUTTON oBtn3 OF oWBar ;
                 TOOLTIP "Saida Normal" ; // Exclui definitivamente a tarefa agendada
                 ACTION EXETaskDelete( cTaskName ) GROUP
          SET MESSAGE OF oWnd TO "Testando Schedule Tasks" NOINSET
   ACTIVATE WINDOW oWnd ;
         ON INIT ( ;
            EXETaskEnable( cTaskName ) ; // Habilita a tarefa e caso o aplicativo quebre, ela sera executada
            )
   return nil

////////////////////////////////////////////////////////////////////////////
//
//    Propositos: Permitir a manutencao dos agendamento de tarefas                                                                  
//
////////////////////////////////////////////////////////////////////////////
function EXETaskCreate( cTaskName, cCMDRun )
   // Jose Carlos da Rocha - 02/02/2016
   ShellExecute( GetActiveWindow(), "RUNAS", "SCHTASKS.exe", "/create /tn "+cTaskName+" /TR "+cCMDRun+" /sc MINUTE", "c:\windows\system32", 0)
   return nil
   
function EXETaskDelete( cTaskName )
   // Jose Carlos da Rocha - 02/02/2016
   ShellExecute( GetActiveWindow(), "RUNAS", "SCHTASKS.exe", "/delete /f /tn "+cTaskName, "c:\windows\system32", 0)
   return nil

function EXETaskEnable( cTaskName )
   // Jose Carlos da Rocha - 02/02/2016
   ShellExecute( GetActiveWindow(), "RUNAS", "SCHTASKS.exe", "/change /enable /tn "+cTaskName, "c:\windows\system32", 0)
   return nil

function EXETaskDisable( cTaskName )
   // Jose Carlos da Rocha - 02/02/2016
   ShellExecute( GetActiveWindow(), "RUNAS", "SCHTASKS.exe", "/change /disable /tn "+cTaskName, "c:\windows\system32", 0)
   return nil

function EXETaskEnd( cTaskName )
   // Jose Carlos da Rocha - 02/02/2016
   ShellExecute( GetActiveWindow(), "RUNAS", "SCHTASKS.exe", "/end /tn "+cTaskName, "c:\windows\system32", 0)
   return nil

function EXETaskRun( cTaskName )
   // Jose Carlos da Rocha - 02/02/2016
   ShellExecute( GetActiveWindow(), "RUNAS", "SCHTASKS.exe", "/run /tn "+cTaskName, "c:\windows\system32", 0)
   return nil

function EXETaskQuery( cTaskName )
   // Jose Carlos da Rocha - 02/02/2016
   ShellExecute( GetActiveWindow(), "RUNAS", "SCHTASKS.exe", "/query /fo csv /tn "+cTaskName+" > "+cTaskName+".csv", "c:\windows\system32", 0)
   return nil
Creio que as funções cFileName(), GetModuleFileName(), GetInstance(), ShellExecute(), GetActiveWindow(), façam parte da API do Windows portanto podendo ser usadas em qualquer outra plataforma que não seja somente Fivewin.

Bom trabalho.

Reiniciar sistema que saiu do ar brutalmente

Enviado: 04 Fev 2016 08:31
por asimoes
Rochinha,

Muito bom!

Perguntas:

1-Este executável roda fora da aplicação "vitima" ?
2-A tarefa criada pelo Schtasks.exe restaura a sistuação antes do apagão, ou seja o usuário estava em uma edição em get e/ou texto ou aguma operação de atualização de base em dbf, enfim em qualquer situação critica do sistema?

Reiniciar sistema que saiu do ar brutalmente

Enviado: 09 Fev 2016 01:35
por rochinha
Amiguinhos,

Desculpe a demora, mas estou no interior de Sampa e sem internet. Só VIVO.

ASimoes
Respondendo as suas questoes:
1-Este executável roda fora da aplicação "vitima" ?

Depende do uso que queira fazer. No meu caso uso em meu sistema e caso caia, por erro, etc, uma mensagem com descrição do ocorrido me é enviada via email e o sistema volta ao ar sozinho.

2-A tarefa criada pelo Schtasks.exe restaura a sistuação antes do apagão, ou seja o usuário estava em uma edição em get e/ou texto ou aguma operação de atualização de base em dbf, enfim em qualquer situação critica do sistema?

Não, como você pode ver, existe apenas a programação da tarefa. Neste caso seria útil que uma fotografia fosse tirada de tempos em tempos e salva via background. Uma fotografia do conjunto dos Gets, salva em array ou mem seria útil neste caso. Pesquise no forum por SaveGets

Lembra destes comandos?

#command SAVE GET TO <var> => PUBLIC <var> := M->GetList; M->GetList := {}
#command RESTORE GET FROM <var> => M->GetList := <var>

...

SAVE GET TO ED_LISTA
M->RET_CAMPO := SPACE(20)
@ POS_CURSOR,COL() GET M->RET_CAMPO PICT "@!"
SET CURSOR ON
READ
SET CURSOR OFF
RESTORE GET FROM ED_LISTA

JoseQuintas
Realmente, a prevenção de erros não é apresentada neste quesito e nem mesmo depende disto para o tratamento em si. O tratamento de erros será dado mesmo sem o uso destas características de forma que ao ocorrerem devam alertar ao desenvolvedor de alguma forma, seja por email, sms, de forma mai automática possível afim de auxiliar a manutenção do mesmo ou atendimento ao usuário antes do mesmo contactar o suporte.