PDA

Ver la Versión Completa : Error al abrir app por segunda vez


sEngine
31-07-2023, 12:51:19
Buenos días, a ver si me podeis ayudar. Estoy teniendo un problema con delphi desde hace unas semanas. Por alguna razón me genera mal el ejecutable y a la segunda vez que inicio mi app, recibo este error.



https://www.gemarun.com/error.jpg


Se que el problema no es del código de la app porque he probado a utilizar código antiguo que iba bien, y en cuanto genero el exe vuelve a ocurrirme. La única forma que he conseguido para que no salga el error es poner un showmessage justo antes de que de el mensaje.
Cada vez que genero el exe, funciona bien la primera vez, las siguientes ya no, hasta que reinicio el equipo.
¿Alguna idea?


El codigo inicial (del dpr) es este

var
IniAux: TIniFile;
Mutex : THandle;
begin
Mutex := CreateMutex(nil, True, 'GemaExclusiveMutex');
if (Mutex <> 0) And (Windows.GetLastError = 0) then
begin
try
with Application do
begin
if (ShortDateFormat = 'M/d/yyyy') then
begin
ShortDateFormat:='MM/dd/yyyy';
end;
// showMessage(''); <--- si pongo el showmessage aqui es cuando funciona
CreateForm(TDMFJoya, DMFJoya);
CreateForm(TDM, DM);
CreateForm(TFMain, FMain);
if FMain.bErrorGrave then Exit;
FMain.Visible := False;
FMain.Show;
if not FMain.bModoAutomatico then
begin
FMain.WmAfterCreate;
end;
Run;
end;
finally
if Mutex <> 0 then
begin
DMFJoya.Free();
CloseHandle(Mutex);
end;
IniAux.Free;
end;
end
else
ShowMessage('La aplicación ya está en ejecución');

duilioisola
31-07-2023, 13:15:34
Parece que no liberas el Mutex.
Quizás se crea el mutex, pero da error porque ya existe y luego no se libera.
Yo siempre tengo el create seguido de try..finally. Dentro de esto el resto de la programación.
De esta manera evito la posibilidad de que no se libere por alguna condición escondida en la programación.


o := TComponente.Create();
try
// Trabajar con o
...
finally
o.Free;
end;




var
IniAux: TIniFile;
Mutex : THandle;
begin
Mutex := CreateMutex(nil, True, 'GemaExclusiveMutex');
try
if (Mutex <> 0) And (Windows.GetLastError = 0) then
begin
with Application do
begin
if (ShortDateFormat = 'M/d/yyyy') then
begin
ShortDateFormat:='MM/dd/yyyy';
end;
// showMessage(''); <--- si pongo el showmessage aqui es cuando funciona
CreateForm(TDMFJoya, DMFJoya);
CreateForm(TDM, DM);
CreateForm(TFMain, FMain);
if FMain.bErrorGrave then Exit;
FMain.Visible := False;
FMain.Show;
if not FMain.bModoAutomatico then
begin
FMain.WmAfterCreate;
end;

Run;
end;
DMFJoya.Free();
IniAux.Free;
end
else
ShowMessage('La aplicación ya está en ejecución');
finally
if Mutex <> 0 then
CloseHandle(Mutex);
end;
end;

sEngine
31-07-2023, 14:19:54
Gracias por la ayuda, lo he puesto tal y como has dicho pero me sigue pasando. Tiene que ser otra cosa

pgranados
31-07-2023, 16:48:04
Gracias por la ayuda, lo he puesto tal y como has dicho pero me sigue pasando. Tiene que ser otra cosa

Libera tu componente.
FreeAndNil(objeto)

O usa una función para matar todos los procesos desde el administrador de tareas (puedes pedirle el código a chatGPT)

duilioisola
01-08-2023, 15:59:41
Ahora queda ir probando cada parte...


1- Prueba quitando las partes de MUTEX.


2- Otra cosa que se me ocurre es que se esté tratando de mostrar algo "demasiado pronto". Pon una pausa donde pones el ShowMessage.
Por ejemplo:

with Application do
begin
if (ShortDateFormat = 'M/d/yyyy') then
begin
ShortDateFormat:='MM/dd/yyyy';
end;
// Prueba con esto -----------
Application.ProcessMessages;
// ---------------------------
CreateForm(TDMFJoya, DMFJoya);
CreateForm(TDM, DM);
CreateForm(TFMain, FMain);


3- También deberías probar moviendo la parte donde das formato a ShortDateFormat mas abajo. Puede que esto no sea ThreadSafe.

sEngine
02-08-2023, 12:18:13
Ahora queda ir probando cada parte...


1- Prueba quitando las partes de MUTEX.


2- Otra cosa que se me ocurre es que se esté tratando de mostrar algo "demasiado pronto". Pon una pausa donde pones el ShowMessage.
Por ejemplo:
Código Delphi [-] (https://www.clubdelphi.com/foros/#) with Application do begin if (ShortDateFormat = 'M/d/yyyy') then begin ShortDateFormat:='MM/dd/yyyy'; end; // Prueba con esto ----------- Application.ProcessMessages; // --------------------------- CreateForm(TDMFJoya, DMFJoya); CreateForm(TDM, DM); CreateForm(TFMain, FMain);


3- También deberías probar moviendo la parte donde das formato a ShortDateFormat mas abajo. Puede que esto no sea ThreadSafe.


Lo de la pausa me ha funcionado, no pensé que eso fuera a ayudar pero así ha sido

Muchas gracias a todos por la ayuda!