Função para matar conexões no Protheus

Olá pessoal…

Hoje vou mostrar uma rotina que criei que mata os usuários de uma conexão no Protheus.

Essa função, pega todas os logins ativos em um serviço do Protheus, e tenta matar uma por uma.

Abaixo a função completa desenvolvida:

//Bibliotecas
#Include "Protheus.ch"

/*/{Protheus.doc} zMataTudo
Função que mata todas as conexões ativas do Protheus
@author Atilio
@since 21/09/2017
@version 1.0
@type function
@obs Documentação no TDN
	GetUserInfoArray - http://tdn.totvs.com/display/tec/GetUserInfoArray
	KillUser         - http://tdn.totvs.com/display/tec/KillUser
/*/

User Function zMataTudo()
	Local aArea      := GetArea()
	Local aThreads   := {}
	Local nConexAtu  := 1
	Local nTentativa := 1
	Local nMaxTenta  := 10
	
	//Se não tiver preparado o ambiente (Schedule)
	If Select("SX2") == 0
		RPCSetType(3)
		RPCSetEnv("01", "01", "", "", "")
	EndIf
	
	ConOut("[zMataTudo] Inicio - " + dToC(Date()) + " " + Time())
	
	//Pega todos os usuários conectados
	aThreads := GetUserInfoArray()
	
	//Enquanto houver tentativas para finalizar as threads
	While nTentativa <= nMaxTenta
		//Percorre todas as conexões
		For nConexAtu := 1 To Len(aThreads)
			
			//Se a thread da conexão atual for diferente da thread atual (senão vai matar o processo que mata todos)
			If aThreads[nConexAtu][3] != ThreadId()
				KillUser( aThreads[nConexAtu][1],; //UserName
				          aThreads[nConexAtu][2],; //ComputerName
				          aThreads[nConexAtu][3],; //ThreadId
				          aThreads[nConexAtu][4])  //ServerName
				
				ConOut("[zMataTudo] "+;
				       "(Tentativa "+cValToChar(nTentativa)+") " + ;
				       "Usuario '"+Alltrim(aThreads[nConexAtu][1])+"', " + ;
				       "Server '"+aThreads[nConexAtu][4]+"', " + ;
				       "Thread '"+cValToChar(aThreads[nConexAtu][3])+"', " + ;
				       "Tempo Total de Conexão '"+aThreads[nConexAtu][8]+"' ")
			EndIf
		Next
		
		//Pega novamente todos os usuários conectados
		aThreads := GetUserInfoArray()
		
		//Se ainda houver registros, aumenta a tentativa e espera 1 segundo
		If Len(aThreads) > 1
			nTentativa++
			Sleep(1000)
			
		//Senão finaliza o laço de repetição
		Else
			Exit
		EndIf
	EndDo
	
	ConOut("[zMataTudo] Termino - " + dToC(Date()) + " " + Time())
	
	RestArea(aArea)
Return

Ao executar, ele mostra mensagens no console.log dentro da pasta appserver com os dados dos usuários que foram desligados.

Saída no console.log

Saída no console.log

Bom pessoal, por hoje é só.
Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

2 Responses

  1. Súlivan disse:

    Bom dia,

    Caríssimo, digníssimo Daniel Atílio.
    Só uma observação quanto ao fonte que está perfeito e me quebrou um galho enorme principalmente na hora de parar os serviços para backup.

    Seu fonte no inicio abre o ambiente exatamente aqui.

    //Se não tiver preparado o ambiente (Schedule)
    If Select(“SX2”) == 0
    RPCSetType(3)
    RPCSetEnv(“01”, “01”, “”, “”, “”)
    EndIf

    Porém no final do fonte você não fecha o ambiente assim

    If Select(“SX2”) == 0
    RpcClearEnv() //Libera ambiente
    Endif

    Ao não fechar o ambiente eu peguei uns problemas de travamento no sistema e tals. Adicionei o trecho para fechar o ambiente os travamentos sanaram.

    Atenciosamente.
    Súlivan Simões.

Deixe uma resposta

Terminal de Informação