2010-04-26 12 views
6

Estoy escribiendo un programa de actualización en Delphi7 que se ejecutará una vez, pero necesita muchos archivos para ejecutarse.Programa Delphi autoextraíble

Lo que me gustaría lograr el:

  1. usuario ejecuta exe
  2. Exe descomprime archivos, corre actualizador
  3. Si detecta actualizador y error, solicita al usuario que envíe registro en el correo electrónico
  4. Después de ejecutar el actualizador, se eliminan los archivos temporales (algunos de estos archivos son dlls utilizados por el programa de actualización, por lo que el actualizador debe cerrarse antes de que los archivos puedan eliminarse)

¿Alguien puede recomendar una buena solución? He pensado en usar Inno Setup (demasiado complicado para una tarea tan fácil) o usar un archivo zip autoextraíble (¿pero cómo eliminar los archivos después)?

Gracias!

Respuesta

2

Estoy usando recursos para mi programa de actualización. Era un recurso de compilación con brcc32 que compilar el programa de actualización. Cuando el programa de actualización ejecuta su autocomprobación, compruebe todo y escriba o actualice con los nuevos. pero sobre este proceso tienes que escribir correctamente, eliminar privilegios en donde se ejecutan tus programas.

Estoy agregando un código de muestra a continuación.

archivo exe.rc

newprog RCDATA Application.exe 

archivo makeres.bat

brcc32 exe.rc 

archivo updater.dpr

{$R exe.res} 

archivo de unidad y procedimientos

procedure ExtractRes(resname,fname,ext:string); 
var 
rStream:TResourceStream; 
fStream:TFileStream; 
fNamex:string; 
begin 
fNamex:=ExtractFilePath(Application.ExeName)+fname+'.'+ext; 
if not fileExists(fnamex) then 
begin 
    try 
    rStream:=tresourcestream.Create(hinstance,ResName,RT_rcDATA); 
    fStream := TFileStream.Create(fnamex, fmCreate); 
    fStream.CopyFrom(rStream, 0); 
    finally 
    rStream.Free; 
    fstream.Free; 
    end; 
end; 
end; 

procedure TForm1.Timer1Timer(Sender: TObject); 
var 
apath:string; 
begin 
if Timer1.Enabled then 
    Timer1.Enabled:=false; 
apath:=ExtractFilePath(Application.ExeName); 
lblMesg.Caption:='Backup old version'; 
Application.ProcessMessages; 
if FileExists(apath+'Application_old.bak') then 
    DeleteFile(apath+'Application_old.bak') ; 
while FileExists(apath+'Application.exe') do 
begin 
    RenameFile(apath + 'Application.exe', apath + 'Application_old.bak'); 
    sleep(1); 
    if FileExists(apath+'Application.exe') then 
    begin 
    lblMesg.Caption:='It seems application still running. Waiting for end'; 
    if FileExists(apath+'Application_old.bak') then 
    DeleteFile(apath+'Application_old.bak'); 
    DeleteFile(apath+'Application.exe'); 
    end; 
    Application.ProcessMessages; 
end; 
lblMesg.Caption:='Creating New Version..'; 
Application.ProcessMessages; 
ExtractRes('Application','Application','exe'); 
lblMesg.Caption:='Running New Version...'; 
Application.ProcessMessages; 
WinExec(pchar(apath+'Application.exe'),sw_show); 
Application.ProcessMessages; 
Halt; 
end; 

Creo que esto puede ayudar a su pregunta 1,2,3. Para 4 puedes extender el código.

+0

¡Hola! 1, necesito extraer archivos a un directorio temporal y ejecutar mi programa allí. Algunos dlls deben estar en el mismo directorio que el programa y si el programa se ejecuta sin derechos de administrador, no puede usar el directorio base para la extracción de archivos. 2, Mi programa utiliza un dll para conectarse a la base de datos. Si trato de eliminar el dll después de desconectarlo, los componentes de DB todavía lo usan. Por lo tanto, tendría que llamar a un programa por separado solo para eliminar los archivos que causan todo tipo de problemas – Steve

+0

entiendo. necesita elevación para vista y 7. pero para los usuarios limitados de xp standart debe indicarle al usuario que se ejecute como administrador. No sé xp solución, pero sé que tiene que ejecutar el proceso desde dentro de su código de nuevo con shellexecuteex. si lo busca en google, encontró buenos ejemplos. pero para elevación puedo enviar un proyecto de muestra. –

+1

Así que aquí está la solución final y la suya es la más cercana: he decidido escribir mi propio programa extractor. Pasos: 1, el programa Extractor extrae archivos del recurso 2, el programa Extractor inicia el actualizador principal utilizando ShellExecuteEx 3, una vez que el programa de actualización finaliza, el programa extractor elimina los archivos de la carpeta temporal. Esta resultó ser la mejor solución en lugar de usar mierda de terceros. ¡Gracias! – Steve

12

Personalmente, utilizaría Inno Setup, ya que es muy adecuado para este tipo de tareas. Eliminar archivos es muy fácil usando eventos de scripting y realizando su eliminación como parte del paso del instalador posterior.

+0

De hecho, Inno Setup está diseñado para hacer exactamente lo que usted ha descrito en su pregunta. Claro, hay otras maneras de hacer lo que pediste. –

+1

+1. ¿Qué no le gusta de Inno? Está escrito en Delphi, en caso de que eso ayude. Y hace casi todo lo que necesitas. Si hay otras funciones que no puede lograr con secuencias de comandos (que pueden hacer LOTES), puede escribir un archivo DLL o EXE y llamarlo para obtener más información. –

+0

1, no quiero mostrar ningún cuadro de diálogo Innosetup (Bienvenido a instalar, bla, bla) 2, Si el programa muestra un mensaje de error, ahora habrá dos botones de la barra de tareas, uno de Inno y uno de mi aplicación - confundiendo al usuario. Esto es un no-go. – Steve

0

Quizás no sea una respuesta Delphi, pero si usted compra una licencia para WinRAR puede utilizar la funcionalidad sencilla configuración incorporado (se comprime a SFX archivo y el guión se almacena en un archivo de comentarios)

muy fácil de usar , puede limpiarse y comprimir muy bien!

Cuestiones relacionadas