Como implementar uma rotina para baixar uma atualização do seu sistema se ele está aberto e você não consegue renomear ou apagar ele enquanto aberto?
A maneira mais prática é você criar um atalho para um arquivo de lote (.bat) ao invés de apontar diretamente para o seu sistema. O nome do arquivo de lotes sempre será o mesmo, enquanto que, os arquivos executáveis terão um novo nome a cada versão.
Por exemplo, seu sistema chama-se SISTEMA001.EXE, então você cria um arquivo de lotes chamado SISTEMA.BAT (o nome do arquivo de lotes precisa ser diferente do nome seu sistema para não dar conflito) e dentro dele você chama SISTEMA001.EXE. Daí, você vai criar uma rotina para baixar um novo arquivo de lotes chamando a nova versão do seu sistema, seriam 2 arquivos SISTEMA.BAT e SISTEMA002.EXE. Visto que os usuários estarão executando o SISTEMA001.EXE não haverá problemas de parar a empresa para fazer a atualização.
CLS @ECHO OFF ECHO. Sistema v002 ECHO. Carregando... SISTEMA002.EXE
Neste caso os usuários estão executanto SISTEMA001.EXE e você baixou os arquivos SISTEMA.BAT e SISTEMA002.EXE. Na próxima vez que algum usuário entrar no sistema chamando SISTEMA.BAT já vai chamar a nova versão SISTEMA002.EXE.
EXE de upgrade via BAT2EXE
Agora vamos supor que já exista diversos atalhos para SISTEMA001.EXE e você não quer mudar. Além disso, você quer o ícone do sistema.
Existe uma ferramenta chamada BAT2EXE, eu tenho e vou disponibilizar aqui, mas só roda em 16bits como o Clipper.
Existem outros na internet, mas não funcionam como desejado. Tem um muito especial https://battoexeconverter.com/, mas muito caro para nós brasileiros por conta do preço do dólar. Custa "apenas" $ 89,95 USD!!!
EXE de upgrade via o próprio Clipper, Harbour ou xharbour
Bem, o arquivo fica muito grande, não menos que 300Kb já compactado com o UPX mesmo que você tire as libs rdd do arquivo .bc do hbmake.
Além disso, se você chamar o sistema com o comando RUN ele fica esperando na memória e não surte o efeito desejado porque não vai funcionar o upgrade, pois o arquivo ainda constará como aberto e dará acesso negado.
EXE de upgrade via Linguagem C++
Ora, é só um código pra chamar outro programa! Seria difícil? Como compilar? Certamente o arquivo gerado seria menor...
Sim, meu arquivo deu 50Kb e baixou para 25Kb com o UPX.
Tu acredita que podes compilar o programa com o próprio BCC que tu já usas para compilar via xHarbour?
Vamos criar um arquivo chamado sistema.cpp contendo o nosso código em Linguagem C++:
#include <stdio.h> #include <process.h> int main(void) { puts("Sistema v002"); puts("Carregando..."); spawnl( P_OVERLAY, "sistema002.exe", "sistema002.exe", "Using spawnl", "Arg1", "Arg2", NULL ); return 0; }
Existem vários exemplos na web para chamar um executável dentro de um programa em C++, mas nosso caso é específico: tem que chamar o sistema e sair da memória. Este exemplo acima é o que funciona para nós.
Voltando para o nosso caso, estamos rodando o sistema001.exe que detectou uma nova versão e vai baixar um zip contendo sistema.exe e sistema002.exe. Todos os links apontam para sistema.exe. A cada nova versão você vai dar um novo nome ao seu sistema e compilar sistema.cpp chamando esse novo nome.
Para compilar basta executar:
bcc32 sistema.cpp
Depois baixe mais ainda o tamanho do arquivo assim:
upx -9 sistema.exe
Agora só falta incluir um arquivo de ícone ao EXE!
Colocando um ícone dentro do EXE feito em C++
Para inserir um ícone no .exe você precisa compilar um arquivo de script de recurso (.rc) contendo o nome do ícone, é um arquivo de texto. Por exemplo, SISTEMA.RC e seria assim:
ICO_LOGO ICON "SISTEMA.ICO"
Daí você precisa compilar SISTEMA.RC (que é um arquivo de texto) para um arquivo de recurso (.RES) que é um arquivo binário do tipo objeto para imagens, assim:
brcc32 sistema.rc
O comando acima vai resulta num arquivo de recurso chamado SISTEMA.RES. Depois disso o arquivo de recurso pode ser incluído no arquivo executável SISTEMA.EXE.
Agora é diferente, precisa linkar os objetos SISTEMA.OBJ com SISTEMA.RES com o ilink32. Infelizmente não era tão simples como parecia: BRC32 -foSISTEMA.RES -feSISTEMA.EXE
Quando você chama ilink32 temos o seguinte:
C:\SISTEMA>ilink32
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Syntax: ILINK32 objfiles, exefile, mapfile, libfiles, deffile, resfiles
@xxxx indicates use response file xxxx
General Options: -Af:nnnn Specify file alignment
-C Clear state before linking -Ao:nnnn Specify object alignment
-wxxx Warning control -ax Specify application type
-Enn Max number of errors -b:xxxx Specify image base addr
-r Verbose linking -Txx Specify output file type
-q Supress banner -H:xxxx Specify heap reserve size
-c Case sensitive linking -Hc:xxxx Specify heap commit size
-v Full debug information -S:xxxx Specify stack reserve size
-Gn No state files -Sc:xxxx Specify stack commit size
-Gi Generate import library -Vd.d Specify Windows version
-GD Generate .DRC file -Dstring Set image description
Map File Control: -Vd.d Specify subsystem version
-M Map with mangled names -Ud.d Specify image user version
-m Map file with publics -GC Specify image comment string
-s Detailed segment map -GF Set image flags
-x No map -Gl Static package
Paths: -Gpd Design time only package
-I Intermediate output dir -Gpr Runtime only package
-L Specify library search paths -GS Set section flags
-j Specify object search paths -Gt Fast TLS
Image Control: -Gz Do image checksum
-d Delay load a .DLL -Rr Replace resources
Agora me diga: Como é que você iria imaginar que teria que fazer assim:
ilink32 /aa /Tpe c0x32 sistema,sistema,,import32 cw32mt,,sistema.res
Complicado, né? Mas, vejamos:
/aa = 32 bit Windows application
/Tpe = output é um arquivo executável
c0x32.obj = código de arranque (startup) para programas em modo console (texto)
import32.lib = a biblioteca contendo referências para itens que o Windows fornece
cw32.lib = é a biblioteca de tempo de execução (runtime) do compilador
Sendo que você já deve ter compilado antes com o 'BCC32 SISTEMA' para que tenha sido gerado o SISTEMA.OBJ como também o 'BRCC32 SISTEMA.RC' para ter o SISTEMA.RES.
Consulte a lista completa de obj e lib da linguagem C++ aqui.
Estas informações de linkar o ícone eu pesquisei na internet, mas se você olhar para dentro do arquivo .BC gerado pelo hbmake do xharbour você verá algo semelhante, vejamos um trecho:
#BCC LINKER = ilink32 ALLOBJ = c0x32.obj $(OBJFILES) $(OBJCFILES) ALLRES = $(RESDEPEN) ALLLIB = $(USERLIBS) $(LIBFILES) import32.lib cw32.lib #COMMANDS .cpp.obj: $(CC_DIR)\BIN\bcc32 $(CFLAG1) $(CFLAG2) -o$* $** .c.obj: $(CC_DIR)\BIN\bcc32 -I$(HB_DIR)\include $(CFLAG1) $(CFLAG2) -o$* $** .prg.obj: $(HB_DIR)\bin\harbour -D__EXPORT__ -n -go -I$(HB_DIR)\include $(HARBOURFLAGS) -o$* $** .rc.res: $(CC_DIR)\BIN\brcc32 $(RFLAGS) $< #BUILD $(PROJECT): $(CFILES) $(OBJFILES) $(RESDEPEN) $(DEFFILE) $(CC_DIR)\BIN\$(LINKER) @&&! $(LFLAGS) + $(ALLOBJ), + $(PROJECT),, + $(ALLLIB), + $(DEFFILE), + $(ALLRES) !
Observa-se que o xharbour compila aquele tal c0x32.obj da linguagem C++ na variável ALLOBJ na linha nº 4 e na variável ALLLIB, linha nº6, temos as libs da linguagem C++ compiladas juntas com as LIBs do xharbour que são: import32.lib e cw32.lib. Na linha nº24 [em conjunto com a linha nº2] observamos a chamada do ilink32 e a ordem de seus parâmetros.
Arquivo de lote para compilar o programa em C++ com o ícone
Vamos poupar o trabalho e criar um arquivo de lotes para compilar o sistema.exe automaticamente. Vamos chamá-lo de comp.bat. Vejamos como ficaria:
bcc32 %1.cpp brcc32 %1.rc ilink32 /aa /Tpe c0x32 %1,%1,,import32 cw32,,%1.res upx -9 %1.exe
%1 = primeiro parâmetro. Irá receber o nome do programa que será compilado pressupondo que todos os arquivos possuam o mesmo nome para poder funcionar. Exemplo: sistema.cpp; sistema.rc; sistema.res; que irá gerar o sistema.exe.
Linha 1: Compila o programa em C++, transforma .cpp em .obj
Linha 2: Compila o arquivo de script de recurso (.rc) que contém o ícone em um arquivo de recurso (.res)
Linha 3: Linka o arquivo OBJ com o RES transformando-os em um arquivo executável com ícone (.exe)
Linha 4: Compacta o arquivo executável no nível máximo (nº 9)
Para compilar o sistema.exe basta agora chamar "comp sistema":
C:\SISTEMA>comp sistema
Comentários
Show de bola
Não sabia dessa função em C++ . Ficou muito bem explicado esse seu texto.
Páginas