Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Codigo para cerrar una aplicacion, no funciona (https://www.clubdelphi.com/foros/showthread.php?t=95598)

ArtPortEsp 03-03-2022 23:58:55

Codigo para cerrar una aplicacion, no funciona
 
Encontré un código diseñado para hacer un "actualizador" de la aplicación principal, y la lógica detrás de el es la siguiente:

1 . la aplicación principal verifica la fecha del ejecutable (de la misma aplicación) contra la fecha de otro ejecutable en una carpeta en la red
2. si el ejecutable en la red es mas reciente que el ejecutable actual, la aplicación principal ejecuta el "actualizador"
3. el actualizador cierra la aplicación principal, realiza la actualización del ejecutable y ejecuta nuevamente la aplicación principal
4. el actualizador se cierra.

el problema esta en el punto 3, por que el actualizador no cierra la aplicación principal, por consiguiente no puede realizar la actualización (si ejecuta la aplicación principal, lo verifique quitando el código que copia el ejecutable)


este es el código del actualizador :
Código:

uses tlhelp32, ShellApi;

{$R *.dfm}

procedure CloseApplication(const ExeFileName: string);
var
  Entry: PROCESSENTRY32;
  hSnapShot, hProcess: THandle;
begin
    hSnapShot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    Entry.dwSize:= SizeOf(PROCESSENTRY32);
    if Process32First(hSnapShot, Entry) then
          while Process32Next(hSnapShot, Entry) do
              if Entry.szExeFile = ExeFileName then
              begin
                    hProcess := OpenProcess(SYNCHRONIZE + PROCESS_TERMINATE,
                                False,
                                Entry.th32ProcessID);

                    if hProcess <> 0 then TerminateProcess(hProcess, 0);

                    CloseHandle(hProcess);
              end;
end;

procedure Actualizar;
begin
    Sleep(4000);
    ShowMessage('Actualización terminada');
end;

procedure TForm1.FormActivate(Sender: TObject);
var
    I: Integer;
    xejecuta : boolean;
begin
    for I := 0 to ParamCount() do
    begin
        if ParamStr(I) = 'd9705s9909' then
        begin
              xejecuta := true;
              break;
        end
        else
              xejecuta := false;
    end;

    if xejecuta = false then
    begin
          MessageDlg('Este programa no puede ser ejecutado directamente.', mtError, [mbOK], 0);
          Application.Terminate;
    end
    else
    begin
          CloseApplication('asapm.exe');
          Actualizar;
          ShellExecute(Handle,
                        'open',
                        'asapm.exe',
                        nil,
                        nil,
                        SW_SHOWNORMAL);
          Close;
    end;
end;

realizando una prueba sencilla (con otro ejecutable que sustituyera la aplicación principal), si parece funcionar correctamente, aunque el código para llamar el actualizador es exactamente el mismo:

codigo que ejecuta el actualizador desde la aplicación principal:

Código:

              if (MessageDlg('Existe una nueva version del sistema, deseas actualizarlo en este momento?', mtWarning, [mbYes, mbNo], 0) = mrYes) then
              begin
                    ShellExecute(Handle,
                      'open',
                      'AU.exe',
                      Pchar('d9705s9909'),
                      nil,
                      SW_SHOWNORMAL);
              end;

alguna idea de por que no se cierre la aplicacion principal?

escafandra 04-03-2022 00:25:11

No es recomendable matar una aplicación con TerminateProcess, sería mejor que la aplicación se cierre de forma natural, para ello el actualizador podría pasar un parámetro o enviar un mensaje de usuario para que la APP se cierre ella misma. Si quieres investigar esa vía, esto te puede interesar: Pasar parámetros en caliente



Si quieres cerrar a lo bruto con TerminateProcess, ten en cuenta que muchas veces hay problemas de permisos o privilegios que pueden impedirlo. Aquí tienes un ejemplo.




Saludos.

ArtPortEsp 04-03-2022 17:50:35

Gracias ESCAFANDRA, lo revisare!

ArtPortEsp 04-03-2022 18:05:18

ESCAFANDRA, a que te refieres con "enviar un mensaje de usuario para que la APP se cierre ella misma"?

escafandra 04-03-2022 18:31:59

Cita:

Empezado por ArtPortEsp (Mensaje 545810)
ESCAFANDRA, a que te refieres con "enviar un mensaje de usuario para que la APP se cierre ella misma"?

Si conoces el Hanle de una ventana (FindWindow) se le puede enviar un mensaje windows. Estos mensajes están definidos por un número entero del rango 0 - 018Fh. Apartir de 400h (WM_USER) son mensajes definidos por usuario.
Si tu App es programada para cerrarse cuando recibe cierto mensaje, tu objetivo está completo.


Saludos

ArtPortEsp 04-03-2022 18:47:45

Cita:

Empezado por escafandra (Mensaje 545811)
Si conoces el Hanle de una ventana (FindWindow) se le puede enviar un mensaje windows. Estos mensajes están definidos por un número entero del rango 0 - 018Fh. Apartir de 400h (WM_USER) son mensajes definidos por usuario.
Si tu App es programada para cerrarse cuando recibe cierto mensaje, tu objetivo está completo.


Saludos

Algun link para investigar al respecto?

ArtPortEsp 04-03-2022 18:51:38

Cita:

Empezado por ArtPortEsp (Mensaje 545812)
Algun link para investigar al respecto?

encontré este... https://www.cryer.co.uk/brian/delphi...ow_message.htm

estudiando....;)


La franja horaria es GMT +2. Ahora son las 15:29:26.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi