Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   evitar doble ejecucion en el programa... (https://www.clubdelphi.com/foros/showthread.php?t=22957)

uper 01-07-2005 23:13:19

evitar doble ejecucion en el programa...
 
Saludos

tengo una pregunta para implementar el codigo de evitar doble ejecucion de la aplicacion por medio de semaforos, en mi caso en la forma principal ejecuto en el evento Oncreate codigo para las excepciones, y en el evento onshow lo uso para lanzar una forma de password.

el codigo de semaforos es este:
procedure TfrmPrinc.FormCreate(Sender: TObject);
var Sem : THandle;
begin
Sem := CreateSemaphore(nil,0,1,'PROGRAM_NAME');
if ((Sem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)) then
begin
CloseHandle( Sem );
ShowMessage('This program is already running.'+ 'Este programa ya se está ejecutando...');
Halt;
end;

end;

lo que hice es declarar un procedimiento llamado procedure Ejecucion(); en la seccion private del form principal, y luego lo llamo en oncreate

Ejecucion;
Application.OnException:= EcepcionException;
CargarDiccionario(ExtractFilePath(Application.ExeName) + NombreDiccio);
//para que capte las excepciones.

se ejecuta sin problemas pero si lo ejecuto otra vez me da el error programado de doble ejecucion pero despues me da el error que ha efectuado operacion no admitida, y el error runtime error 216 at 000587b9.

yo lo probe en una aplicacion sencilla en oncreate y funciona por que no le estoy agregando mas codigo de las excepciones, ahora que lo estoy implementando no resulta, hay algo para evitar esto.

mucha gracias.

marcoev 02-07-2005 03:31:19

encontre el siguiente codigo en trucomania

Cita:

Simplemente detectaremos si hay otro ejecutable ejecutándose que se llame igual que el nuestro.

-Añade 'TLHelp32' en el uses de tu form
-Añade esta función en el implementation de la form:

function ProgramaAbiertoDosVeces:Boolean;
var
Datos :TProcessEntry32; {Estructura interna de datos de un proceso}
hID :DWord; {identificador del proceso}
Snap :Integer;
NombreArchivo :String; {path del archivo original}
Repetido :Boolean; {true si el programa se ha abierto dos veces}
Handle1 :Hwnd; {thandle}
Contador :Integer; {Contador de aperturas}

begin
Contador:=0;
NombreArchivo:=Application.Exename;
Repetido:=False;
GetWindowThreadProcessId(Handle1,@hID);
Snap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
try
Datos.dwSize:=SizeOf(Datos);
if(Process32First(Snap,Datos))then
begin
repeat
if NombreArchivo=StrPas(Datos.szExeFile) then
begin
Inc(contador);
if Contador>=2 then Repetido:=true;
end;
until (not(Process32Next(Snap,Datos))) or (Repetido);
end;
finally
Windows.CloseHandle(Snap);
end;
Result:=Repetido;
end;

-Ahora, pon este código en el evento OnCreate de la form principal:

procedure TForm1.FormCreate(Sender: TObject);
begin
if ProgramaAbiertoDosVeces then
begin
showmessage('El programa ha sido abierto mas de una vez');
Application.terminate;
end;
end;


edgusano 02-07-2005 17:31:34

Pues. Yo utilizo una UNIT que tiene ROMAN publicada en su pagina del club delphi que sirve para eso, por demas es excelente, pruebala.

serhasae 03-07-2005 00:41:23

Donde esta la unit esa, podrias ponerla Edgusano. No la veo. O que la ponga roman. saludos.

roman 03-07-2005 01:46:25

http://www.clubdelphi.com/users/roman

// Saludos

uper 04-07-2005 19:44:40

saludos

tengo un error que me marca en la funcion declarada en la parte de private:
private
function ProgramaAbiertoDosVeces:Boolean; ---->>error.
{ Private declarations }

--->>[Warning] uSistema.pas(99): Variable 'Handle1' might not have been initialized

en donde debe declararse esta variable, ya la coloque afuera despues de la declaraciones privadas y publicas y aun asi da el error
en este caso esta dentro de la funcion:

var
Handle1 :Hwnd; {thandle}

gracias

raco 07-07-2005 01:00:05

Yo tambien he utilizado este metodo y me funciona muy bien, lo unico que tienes q hacer es seguir las instrucciones de la pagina. Agrega el archivo .pas a tu proyecto igual como viene en la pagina y agregalo al modulo del programa principal (dpr) en la clausula uses, como dice en la pagina para que se ejecute primero. Es todo lo que tienes que hacer.

cyberpablis 20-08-2016 17:02:24

La solucion:
 
Directamente en el DPR:
Código Delphi [-]
  // Verifico que no exista una instancia previa del programa en ejecución.-
  Application.Title := 'Mi aplicacion';
  if CreateFileMapping($FFFFFFFF, nil, PAGE_READONLY, 0, 32, 'PABLOR_TAGGED') <> 0 then
      if GetLastError() = ERROR_ALREADY_EXISTS then
          begin
          Application.MessageBox('Ya existe una instancia de la aplicación ejecutándose', 'Atención', MB_ICONWARNING);
          ExitProcess(1);
          end;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;

Angel.Matilla 28-03-2017 19:10:44

Estaba buscando información sobre otra cosa y he ido a dar con este hilo. Aunque es ya de hace unos meses os pongo aquí como lo resuelvo yo en BCB.

En el fichero que lanza la aplicación (el .cpp asociado a su homónimo .bpr):
Código:

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    HWND OtraVentana;
    AnsiString cVersion = "Mi aplicación";

    OtraVentana = FindWindow(NULL, cVersion.c_str());
    if (OtraVentana != NULL)
    {
          Application->MessageBox("¡¡¡LA APLICACIÓN YA ESTÁ ACTIVA!!!", cVersion.c_str(), 48);
        ShowWindow(OtraVentana, SW_RESTORE);
        SetForegroundWindow(OtraVentana);
          return 0;
    }
    try
    {
          Application->Initialize();
          Application->Title = cVersion;
          Application->CreateForm(__classid(TfPersona), &fPersona);
          Application->Run();
    }
    catch(Exception &exception)
    {
          Application->ShowException(&exception);
    }
    catch(...)
    {
          try
          {
              throw Exception("");
          }
          catch(Exception &exception)
          {
              Application->ShowException(&exception);
          }
    }
    return 0;
}
//---------------------------------------------------------------------------

Me parece un método sencillo y elegante.

MAXIUM 28-03-2017 19:36:02

Mutex, no olviden el Mutex.

Google: delphi + mutex + example


La franja horaria es GMT +2. Ahora son las 01:39:57.

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