Página 1 de 1

Atualizar executável sem reiniciar o servidor

Enviado: 27 Jun 2022 08:34
por Poka
Bom dia

Toda vez que tenho que atualizar o exe no cliente tem que reiniciar o servidor.

O windows diz que o sistema está sendo utilizado.

Alguém sabe como resolver?

Obrigado

Poka

Atualizar executável sem reiniciar o servidor

Enviado: 27 Jun 2022 08:48
por Mario Mesquita
Bom dia.

Já vi acontecer, nem senpre é no servidor mas em alguma máquina da rede. Não sei se tem ligação mas quando vi acontecer, houve uma tentaiva de atualização com o sistema aberto em alguma máquina da rede. Aí só restartando a máquina que estava com o programa aberto. Pq fica um "fantasma", o Windows não entende que já fechou o programa.

Então quando faço atualização, peço para fecharem o programa em todas as máquinas da rede. Nem sempre acontece, é meio aleatório.

Sds,
Mario.

Atualizar executável sem reiniciar o servidor

Enviado: 27 Jun 2022 10:21
por Itamar M. Lins Jr.
Olá!
Eu não tenho esse problema.
Eu renomeio o EXE. Deixo ele lá com outro nome.

Saudações,
Itamar M. Lins Jr.

Atualizar executável sem reiniciar o servidor

Enviado: 27 Jun 2022 10:48
por Fernando queiroz
hoje meu método de atualização ficou assim.
cada estação de trabalho tem o seu .EXE
quando tenho uma nova versão/release eu atualizo a minha maquina na base de dados do cliente
após isso todos as maquinas que entrarem no sistema verifica se esta atualizada
caso não esteja atualizada ela executa o aplicativo ATUALIZA.EXE baixando do meu servidor FTP o novo .EXE

com isso eu nao tenho de me preocupar de estacoes sem atualizacao , pois no momento que ela entrar novamente vai ser
obrigada a atualizar

Atualizar executável sem reiniciar o servidor

Enviado: 01 Jul 2022 15:39
por carlaoonline
Eu resolvi meu problema de atualização dessa maneira:

Antigamente eu mapeava uma unidade de rede e colocava em todo terminal um atalho para o executável que fica nesse unidade mapeada lá no servidor, mas toda vez que tinha que atualizar o app principal então tinha que ficar ligando para todos os ramais......um saco....


Hoje, o executável fica no PC do usuário, sendo executado ali. Apenas o acesso ao banco de dados que é via rede.

Em todo terminal crio uma pasta chamada C:\SISTEMA (Pode ser qualquer pasta em qualquer unidade)


Nessa pasta, eu coloco 2 executáveis:

VERIFICA_ATUALIZACAO.EXE
APP_PRINCIPAL.EXE
(Pode ser qualquer nome de arquivos tb).



Na área de trabalho do cliente, o atalho criado NÃO É PARA O APP_PRINCIPAL, é um atalho para o executável VERIFICA_ATUALIZACAO.EXE

Ele verifica no servidor (seja onde for) se existe uma atualização disponível para o APP_PRINCIPAL.

Se existir, então atualiza o APP_PRINCIPAL.EXE e DEPOIS executa-o, caso não existir atualização, então executa o APP_PRINCIPAL existente na pasta.


Por sua vez, o APP_PRINCIPAL faz a mesma tarefa, porém em relação ao executável VERIFICA_ATUALIZACAO.EXE, que caso haja uma atualização disponível para ele, daí já atualiza, ou seja, um atualiza o outro.


E ainda em ambos executáveis deixo programado sentenças do tipo IF FILE("EXEC1.EXE") , IF FILE("EXEC1.BAT") .... no inicio de cada APP, que se for encontrado determinado executável então deve executa-lo tb.


(Note que no atalho na área de trabalho eu coloco o nome que quiser, tipo: Faturamento, Emissão, Cadastro, Vendas etc...com o ícone que eu quiser tb... o cliente não precisa saber o que é o que ou o que faz o que....)


Tanto o VERIFICA_ATUALIZACAO.EXE quanto o APP_PRINCIPAL.EXE dependem de suas datas internas serem maiores ou iguais que a data que existe na tabela ATUALIZA no banco de dados lá no servidor, caso contrário o executável não será executado.

No APP_PRINCIPAL.EXE é feita seguidas verificações durante sua execução nessa data de atualização lá no banco de dados do servidor.

Então se nesse momento eu mudar a data nessa tabela lá no servidor para a data de hoje de ambos executáveis, então o APP_PRINCIPAL.EXE irá parar de funcionar (claro que com o devido fechamento das tabelas assim que o usuário terminar o lançamento atual) e o VERIFICA_ATUALIZACAO.EXE tb não funcionará mais até receberem a nova compilação, ou seja, tenho o controle total de parada e de atualizações independente por executável e o usuário é sempre notificado sobre nova atualização disponível.

Note também que a atualização se dá pela data interna do aplicativo comparada com a do banco de dados no servidor, nada a ver com data de criação ou compilação. Posso compilar 10 vezes o aplicativo mas se eu não mudar a data do banco de dados nem do aplicativo nada ira acontecer.

Óbvio que não irei bloquear os dois no mesmo tempo, senão quem vai atualizar quem?

Atualizar executável sem reiniciar o servidor

Enviado: 02 Jul 2022 14:29
por dbsh
Como o Itamar falou a melhor forma e renomear para um arquivo temporário, porque não da erro, e podem continuar a usar o sistema.
Ao saírem e entrarem de novo vão usar a nova versão.
Coloque na entrada do sistema para procurar os arquivos temporários e excluir, dando erro ignore.
Para forçar sair do sistema, crie um sinalizador, um arquivo de uso exclusivo, criado no seu terminal
Nas rotinas mais usadas ou ao selecionar uma opção no menu, tente excluir este arquivo, se não conseguir faça a saída do sistema, um exemplo abaixo.

As rotinas abaixo foram tiradas de parte da minha biblioteca, não deu para testar, se for útil é só usar.
Pode ter erro de logica, devido as algumas alterações, e retirada de algumas funções.

LayOut das copias:
arquivo1.exe,arquivo2.exe,arquivo2.exe,...

LayOut arquivos temporarios:
tmp_1.exe,tmp_2.exe,tmp_3.exe,...

O código abaixo não esta funcional é uma parte do meu sistema de atualização, é só para você ter uma ideia de como fazer

EX:
arquivo.new.exe - nova versão, mantem copia da versão atual
arquivo.atu.exe - sobrepor versão atual

Código: Selecionar todos


STATIC nHandle := 0

STATIC FUNCTION AtualizarVersaoNew(sArqNew)
LOCAL sArqExe, sArqTmp1, sArqTmp2, nCopias, aCopia, xx

IF Empty(sArqNew) .or. !File(sArqNew)
    RETURN .F.
ENDIF

sArqExe := Lower(PathToFile( sArqNew ))  // pega nome arquivo
sArqExe := StrTran(sArqExe, '.new.', '.')

FOR xx := 1 TO 10
   IF '(' + NTrim(xx) + ')' $ sArqExe
      sArqExe := StrTran(sArqExe, '(' + NTrim(xx) + ')', '')
   ENDIF
NEXT

nCopias   := Val(IniRead('boot', 'copia versao ' + PathToFile(sArqExe), '10'))
aCopia    := { {sArqNew, sArqExe } }

FOR xx := 1 TO nCopias
    IF xx = 1
        sArqTmp1 := sArqExe
    ELSE
        sArqTmp1 := StrTran(sArqNew, '.new.', xStr(xx - 1) + '.')
    ENDIF
    IF File(sArqTmp1)
        sArqTmp2 := StrTran(sArqNew, '.new.', xStr(xx) + '.')
        IF AScan(aCopia, {|p| FileDate(p[1]) = FileDate(sArqTmp1) .and. FileTime(p[1]) = FileTime(sArqTmp1) }) = 0
            AAdd(aCopia, {sArqTmp1, sArqTmp2})
        ELSE
            EXIT
        ENDIF
    ELSE
        EXIT
    ENDIF
NEXT

FOR xx := Len(aCopia) TO 1 STEP -1
    IF !BoniFileRenExc( aCopia[xx, 1], aCopia[xx, 2] ) // exclui destino antes de renomear se existir
        RETURN .F.
    ENDIF
NEXT

RETURN .T.

FUNCTION AtualizarVersaoAtu(sArqAtu)
LOCAL sPath, sArqExe, xx

IF Empty(sArqAtu) .or. !File(sArqAtu)
   RETURN .F.
ENDIF

sPath   := PathToFile( sArqAtu, .T. )  // pega path do arquivo
sArqExe := Lower(PathToFile( sArqAtu ))
sArqExe := StrTran(sArqExe, '.atu.', '.')

FOR xx := 1 TO 10
   IF '(' + NTrim(xx) + ')' $ sArqExe
      sArqExe := StrTran(sArqExe, '(' + NTrim(xx) + ')', '')
   ENDIF
NEXT

IF File(sArqExe)
   IF !BoniFileRenDest(sPath + sArqExe, sPath + 'tmp_' + sArqExe) //renomeia primeiro destino se existir, depois renomeia de orig para dest
      RETURN .F.
   ENDIF
ENDIF

RETURN BoniFileRen(sArqAtu, sArqExe)

FUNCTION aVersao(sPath, lSinalizador)
LOCAL aVersao, aTmp, xx

DEFA sPath TO PathAtual()
DEFA lSinalizador TO .T.

sPath   := TrataPath(sPath)
aVersao := {}

aTmp := Directory(sPath + '*.new.*')
FOR xx := Len(aTmp) TO 1 step - 1
   IF  Upper(Right(aTmp[xx, 1], 3)) = '.ON'
       LOOP
   ENDIF
   IF Empty(lSinalizador) .or. File(sPath + aTmp[xx, 1] + '.on') // sinalizador, se esta baixado todas dependências
      aTmp[xx, 1] := Lower(sPath + aTmp[xx, 1])
      aadd(aVersao, aTmp[xx])
   ENDIF
NEXT

aTmp := Directory(sPath + '*.atu.*')
FOR xx := Len(aTmp) TO 1 step - 1
   IF  Upper(Right(aTmp[xx, 1], 3)) = '.ON'
       LOOP
   ENDIF
   IF Empty(lSinalizador) .or. File(sPath + aTmp[xx, 1] + '.on')   // sinalizador, se esta baixado todas dependência
      aTmp[xx, 1] := Lower(sPath + aTmp[xx, 1])
      aadd(aVersao, aTmp[xx])
   ENDIF
NEXT

aTmp := Directory(sPath + '*.exe.exe')
FOR xx := Len(aTmp) TO 1 step - 1
   IF Empty(lSinalizador) .or. File(sPath + aTmp[xx, 1] + '.on')   // sinalizador, se esta baixado todas dependência
      aTmp[xx, 1] := Lower(sPath + aTmp[xx, 1])
      aadd(aVersao, aTmp[xx])
   ENDIF
NEXT

aSort(aVersao,,, {|x, y| (x[3] < y[3]) .or. (x[3] = y[3] .and. x[4] < y[4])} )

RETURN aVersao

Código: Selecionar todos


// na entrada do sistema, nas opções mais usadas, EX: inicio da venda/pedido/cadastros/ao selecionar uma opção do menu principal
PROCEDURE Main()

IF IsBloqueado()
  Alerta('sistema em manutenção')
  quit
  RETURN
ENDIF

FUNCTION Bloqueio()
LOCAL sArq

IF nHandle > 0
  RETURN .T.
ENDIF

IF IsBloqueado()  // esta bloqueado em outro terminal
  RETURN .F.
ENDIF

sArq := 'blq_manu'

nHandle := FCreate( sArq )
IF nHandle > 0
    FClose( nHandle )
    nHandle := FOpen( sArq, 33 ) //somente escrita e exclusivo
    //salvar informação para saber que terminal tem o bloqueio
ENDIF

IF !nHandle > 0
    //Alert( 'Nao foi posivel criar sinalizador do sistema ' + cArq )
    FErase(cArq)
    RETURN .F.
ENDIF

RETURN .T.

// desbloquear
FUNCTION DesBloqueio()
LOCAL sArq

IF nHandle = 0 
  RETURN .T.
ENDIF

sArq := 'blq_manu'

FClose( nHandle )
FErase(sArq)

RETURN .T.

// se foi bloqueado em outra estação de trabalho
FUNCTION IsBloqueado( sArq)

IF nHandle > 0
  RETURN .F.
ENDIF

IF File( sArq )
  FErase( sArq )
ENDIF

RETURN File( sArq )

// se bloqueio me pertence
FUNCTION Isblocked( sArq )
RETURN nHandle > 0


Atualizar executável sem reiniciar o servidor

Enviado: 02 Jul 2022 17:09
por Poka
Boa tarde

Obrigado pelas respostas.
Um exe pra cada terminal nunca gostei.
se funcionar renomear o exe ta resolvido, mas acho que ja fiz isso.
acessei agora o servidor e permite , não sei se porque não tem nenhum terminal ligado.
Vou ver segunda-feira. se permitir renomear tranquilo. Renomear é sempre a segunda opção, primeiro tento excluir. Segunda feira retorno.
Obrigado por enquanto.

Poka

Atualizar executável sem reiniciar o servidor

Enviado: 03 Jul 2022 09:16
por JoséQuintas
http://www.jpatecnologia.com.br/arquivos/sjpa.exe

Está alterado pra usar o nome depois do "S" como nome do EXE.
Com o nome de SJPA.EXE vai carregar JPA.EXE, JPA1.EXE, JPA2.EXE, etc. o arquivo com data/hora mais recente.
Na hora de atualizar, manual ou automático, é só salvar com um nome disponível JPAn.EXE

Se seu aplicativo se chama MINHOCA.EXE, só renomear pra SMINHOCA.EXE e deixar na pasta.

Tanto faz se é pasta mapeada ou direta, seu aplicativo vai receber o PATH como default.
Pode ser C:\ ou C:\pasta ou F:\pasta ou \\servidor\pasta.

Não se esqueça, na atualização do EXE, de eliminar EXEs antigos, pra não acumular.
Costumo deixar os 3 últimos por precaução.

Já postei o fonte dele algumas vezes por aqui.

O EXE vai ser carregado com ShellExecute(), portanto, sem ocupar espaço de memória, ou ficar carregado na memória.

Atualizar executável sem reiniciar o servidor

Enviado: 10 Ago 2022 11:29
por Poka
Bom dia.

Obrigado à todos por responder,

Realmente, dei mancada, só renomear já resolve, a hora que o sistema estiver pronto, aí vou ver uma solução nas respostas acima para poder atualizar automaticamente via sistema.

Grato


Poka