Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-02-2009
Eyewitness Eyewitness is offline
Registrado
 
Registrado: mar 2008
Posts: 6
Poder: 0
Eyewitness Va por buen camino
Cómo evitar ejecutar bloques en el IDE

Hola a todos.

¿Alguien sabe cómo ejecutar una porción del código Delphi SOLAMENTE cuando se ejecuta el .exe desde fuera del IDE? Es decir, mantener activa esa parte del código para probar un ejecutable en el entorno del S.O, pero ignorarla cuando pulse "run" en el IDE de Delphi.

No tengo ni idea de compiler directives, así que no sé si hay alguna que haga esto.

Saludetes.
Responder Con Cita
  #2  
Antiguo 20-02-2009
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
En tu código utilizas esto:

Código Delphi [-]
 ...
{$IFDEF SOLO_IDE}    
  // lo que quieres que se ejecute sólo en el IDE
  _LogErrores(...)  
{$ENDIF}

En las opciones del proyecto en Directories/Conditionals hay una sección que dice "Conditional Defines".
Cuando esté trabajando normalmente en el IDE debe tener ese condicional:



Cuando vayas a generar la version definitiva lo eliminas antes de compilar.

Otra opción (más cómoda para mí) es utilizar un fichero .INC qe añades al proyecto.
En el fichero defines:

Código:
//********************** ATENCION ************************
//************  SE DEBE DESCOMENTAR PARA PRODUCCION ******
{.$DEFINE PRODUCCION}
//********************** ATENCION ************************

{$IFDEF PRODUCCION}     // ==>  ESTAMOS EN PRODUCCION
  //...  condicionales que queremos para producción
  {$DEFINE SOCKETS}
  ....
{$ELSE}
  //...  condicionales que no queremos para produccion (para el IDE)
  {$DEFINE SOLO_IDE}
   ...
{$ENDIF}
En este caso lo único que hay que hacer es:
(1) Cuando estás en el IDE, la linea en rojo debe ser (comentada, con punto):
{.$DEFINE PRODUCCION}

(2) Cuando no estás en el IDE, debe ser (sin punto):
{$DEFINE PRODUCCION}

Así sólo hay que poner o quitar punto al generar version definitiva.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 20-02-2009
Eyewitness Eyewitness is offline
Registrado
 
Registrado: mar 2008
Posts: 6
Poder: 0
Eyewitness Va por buen camino
Gracias, Neftalí. Me das no solamente una opción, sino dos. Deluxe !!

A mí también me parece más interesante por comodidad usar un fichero .inc. Ya mismo me pongo a probar a implementarlo.

Buen finde !!!!
Responder Con Cita
  #4  
Antiguo 20-02-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Hola,

Aunque los condicionales del compilador son -en mi opinión- más que suficientes para aislar partes del código que queremos ejecutar sólo en determinadas ocasiones, tal como apunta Neftalí, me gustaría aclarar que esta técnica no discierne realmente si nuestra aplicación está o no ejecutandose desde el IDE, sólo distingue si al momento de compilar está o no definido un símbolo y hay que manipular éste y recompilar cada vez que deseemos cambiar el comportamiento.


Una manera de distinguir si el IDE está ejecutándose podría ser ésta:

Código Delphi [-]
function IsIDERunning(): Boolean;
begin
  Result := FindWindow('TAppBuilder', nil) <> 0;
end;

aunque resulta bastante ingenua pues sólo detecta si hay una ventana cuya clase se llame 'TAppBuilder' (que es como se llama la ventana principal del IDE de Delphi) pero el IDE podría estar abierto y aún así la aplicación ejecutarse desde fuera.


Una mejor aproximación es encontrando qué proceso lanza nuestra aplicación. Normalmente, si la ejecutamos desde fuera, este proceso será 'explorer.exe', mientras que si lo hacemos desde el IDE será 'delphi32.exe' (al menos para Delphi 7, que es con lo que estoy probando).

Dejo un par de funciones para esto último. La primera busca información de un proceso a partir de su identificador y la segunda deterrmina si la aplicacion la lanzó el IDE (1).

Código Delphi [-]
{
  Busca información de un proceso a partir de su identificador.

  La información se devuelve en el parámetro ProcInfo y la función
  devuelve true o false dependiendo de si se encontró  o no el
  proceso.

  Requiere la unidad TlHelp32
}
function FindProcess(ProcId: Cardinal; out ProcInfo: TProcessEntry32): Boolean;
var
  SnapShot: THandle;
  TempProcInfo: TProcessEntry32;

begin
  SnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

  if SnapShot <> INVALID_HANDLE_VALUE then
    try
      ZeroMemory(@ProcInfo, SizeOf(ProcInfo));
      
      if Process32First(SnapShot, TempProcInfo) then
        repeat
          Result := TempProcInfo.th32ProcessID = ProcId;
          
          if Result then
            ProcInfo := TempProcInfo;
        until Result or not Process32Next(SnapShot, TempProcInfo)
      else
        Result := false;
    finally
      CloseHandle(SnapShot);
    end
  else
    raise Exception.Create('Cannot take snapshot of processes');
end;

{
  Determina si la aplicación se lanzó desde el IDE de delphi o no.
}
function RunningFromIDE(): Boolean;
var
  ProcInfo: TProcessEntry32;

begin
  Result :=
    FindProcess(GetCurrentProcessId(), ProcInfo) and
    FindProcess(ProcInfo.th32ParentProcessID, ProcInfo) and
    (ProcInfo.szExeFile = 'delphi32.exe');
end;

(1) Desde luego, estrictamente hablando, la función RunningFromIDE sólo determina si la aplicación fue lanzada por un proceso llamado 'delphi32.exe' y cualquiera puede hacer un proceso que así se llame y que no sea el IDE pero bueno, no estamos tratando de establecer un mecanismo de seguridad como los de tiempos antiguos en que los creadores de componentes shareware intentaban restringir su uso al IDE.

Regresando al punto original, podríamos usar esta función para ejecutar bloques condicionalmente dependiendo de si la aplicación corre desde el IDE o no:

Código Delphi [-]
if RunningFromIDE then
begin
  {
    Código que se ejecuta sólo desde el IDE
  }
end;

Aunque, como digo, la compilación condicional es más que suficiente para estos menesteres, creo que en ocasiones esta técnica puede ser cómoda pues nos evita estar cambiando los símbolos. Por ejemplo, ¿no se aburren de escribir una y otra vez el usuario y contraseña de su sistema cuando están haciendo pruebas? Podríamos poner

Código Delphi [-]
{$ifdef DEBUG}
txtUsuario.Tet := 'yomero';
txtPassord.Text := 'secreto';
{$endif}

de manera que cada vez que ejecutemos el sistema ya estén escritos nuestros datos. Pero ¿qué pasa si nos olvidamos de quitar el símbolo DEBUG antes de entregar la nueva versión?

Podríamos poner:

Código Delphi [-]
if RunningFromIDE then
begin
  txtUsuario.Tet := 'yomero';
  txtPassord.Text := 'secreto';
end;

y despreocuparnos de posibles olvidos.

// Saludos
Responder Con Cita
  #5  
Antiguo 20-02-2009
Eyewitness Eyewitness is offline
Registrado
 
Registrado: mar 2008
Posts: 6
Poder: 0
Eyewitness Va por buen camino
Muchas gracias, Román.

Ahora ya tengo trabajo para el fin de semana, porque cada método es ventajoso en unos aspectos frente a los otros dos...

Gracias a ambos, nuevamente, por vuestras soluciones.
Responder Con Cita
  #6  
Antiguo 26-07-2013
agustibaldo agustibaldo is offline
Miembro
 
Registrado: nov 2006
Posts: 105
Poder: 18
agustibaldo Va por buen camino
Estaba buscando una solución similar a la que daban para el caso de Eyewitness y tomé la idea de roman
Estoy utilizando Delphi 2010 y me encuentro con que no detecta el proceso. Hago la siguiente prueba:

Código Delphi [-]
   if RunningFromIDE() then
      ShowMessage('Debug!')
   else
      ShowMessage('Release!');

En la declaración de la función cambié: ProcInfo.szExeFile = 'delphi32.exe' por ProcInfo.szExeFile = 'bds.exe' y también por ProcInfo.szExeFile = 'bds.exe *32', pero cuando ejecuto la aplicación desde el IDE me aparece siempre el mensaje Release!
Tienen idea si hay que cambiar algo de la función para que trabaje correctamente?

Por otro lado les consulto: mi intención con esto es separar los ambientes de Desarrollo/Testing con Producción. Trabajo con SQL Server y realizo las conexiones a través de dbexpress donde los parámetros de conexión se encuentran en un dbxconnection.
La idea es detectar si el usuario corre la aplicación desde el IDE (modo Debug) o desde el acceso directo a la misma y a partir de eso conectar a las bases de datos de Desarrollo y Producción respectivamente. Es decir, cuando trabaje sobre el IDE solo use las bases de datos de desarrollo.

He investigado bastante pero no he encontrado una "forma estándar" de separar estos ambientes para evitar que los desarrolladores utilicen los datos de producción accidentalmente mientras realizan testing.

Espero que me puedan aconsejar sobre que modelo me conviene adoptar.
Desde ya, muchas gracias.
Responder Con Cita
  #7  
Antiguo 26-07-2013
Avatar de movorack
[movorack] movorack is offline
Miguel A. Valero
 
Registrado: feb 2007
Ubicación: Bogotá - Colombia
Posts: 1.346
Poder: 20
movorack Va camino a la famamovorack Va camino a la fama
Hola,
Usa DebugHook para verificar si estás trabajando desde el IDE.

Código Delphi [-]
  if DebugHook = 1 then
  begin
    //Ejecutandose desde el IDE
  end;
__________________
Buena caza y buen remar... http://mivaler.blogspot.com
Responder Con Cita
  #8  
Antiguo 26-07-2013
Avatar de movorack
[movorack] movorack is offline
Miguel A. Valero
 
Registrado: feb 2007
Ubicación: Bogotá - Colombia
Posts: 1.346
Poder: 20
movorack Va camino a la famamovorack Va camino a la fama
Por otro lado con las directivas de compilación se puede asegurar que el ejecutable se comporte de una u otra manera en la fase de desarrollo.

Ej: Omitir login, otorgar permisos de superusuario, conectar a un servidor de bases de datos en especifico, etc...

Tal como lo explica neftalí :

Cita:
Empezado por Neftali Ver Mensaje
En tu código utilizas esto:

Código Delphi [-]
 ...
{$IFDEF SOLO_IDE}    
  // lo que quieres que se ejecute sólo en el IDE
  _LogErrores(...)  
{$ENDIF}

En las opciones del proyecto en Directories/Conditionals hay una sección que dice "Conditional Defines".
Cuando esté trabajando normalmente en el IDE debe tener ese condicional:



Cuando vayas a generar la version definitiva lo eliminas antes de compilar.

Otra opción (más cómoda para mí) es utilizar un fichero .INC qe añades al proyecto.
En el fichero defines:

Código:
//********************** ATENCION ************************
//************  SE DEBE DESCOMENTAR PARA PRODUCCION ******
{.$DEFINE PRODUCCION}
//********************** ATENCION ************************

{$IFDEF PRODUCCION}     // ==>  ESTAMOS EN PRODUCCION
  //...  condicionales que queremos para producción
  {$DEFINE SOCKETS}
  ....
{$ELSE}
  //...  condicionales que no queremos para produccion (para el IDE)
  {$DEFINE SOLO_IDE}
   ...
{$ENDIF}
En este caso lo único que hay que hacer es:
(1) Cuando estás en el IDE, la linea en rojo debe ser (comentada, con punto):
{.$DEFINE PRODUCCION}

(2) Cuando no estás en el IDE, debe ser (sin punto):
{$DEFINE PRODUCCION}

Así sólo hay que poner o quitar punto al generar version definitiva.
__________________
Buena caza y buen remar... http://mivaler.blogspot.com
Responder Con Cita
  #9  
Antiguo 26-07-2013
agustibaldo agustibaldo is offline
Miembro
 
Registrado: nov 2006
Posts: 105
Poder: 18
agustibaldo Va por buen camino
Excelente!! Funciona perfecto!
muchas gracias!!
Responder Con Cita
  #10  
Antiguo 03-08-2013
Avatar de ozsWizzard
ozsWizzard ozsWizzard is offline
Miembro
 
Registrado: may 2004
Ubicación: Murcia
Posts: 190
Poder: 20
ozsWizzard Va por buen camino
Cita:
Empezado por agustibaldo Ver Mensaje
[...]

Por otro lado les consulto: mi intención con esto es separar los ambientes de Desarrollo/Testing con Producción. Trabajo con SQL Server y realizo las conexiones a través de dbexpress donde los parámetros de conexión se encuentran en un dbxconnection.
La idea es detectar si el usuario corre la aplicación desde el IDE (modo Debug) o desde el acceso directo a la misma y a partir de eso conectar a las bases de datos de Desarrollo y Producción respectivamente. Es decir, cuando trabaje sobre el IDE solo use las bases de datos de desarrollo.

He investigado bastante pero no he encontrado una "forma estándar" de separar estos ambientes para evitar que los desarrolladores utilicen los datos de producción accidentalmente mientras realizan testing.

Espero que me puedan aconsejar sobre que modelo me conviene adoptar.
Desde ya, muchas gracias.
En mi caso, el host de la conexión con SQL Server se mantiene en un fichero INI, de esta forma, es independiente del ejecutable y se puede cambiar si alguna vez hay que debugar algo de producción.

Un saludo
__________________
La Madurez se llama...
~~~Gaia~~~
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
evitar ejecutar la misma aplicacion 2 veces noe API de Windows 13 26-05-2008 19:30:03
Generar bloques de números Natasha Nortman Varios 8 30-03-2008 15:47:54
Esquemas de bloques david.rguez Gráficos 1 01-09-2007 00:05:01
Bloques De Numeros Consecutivos dany2006 C++ Builder 5 15-11-2006 21:06:16
como evitar el timewait fer21unmsm Varios 2 08-05-2006 22:05:52


La franja horaria es GMT +2. Ahora son las 13:42:48.


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
Copyright 1996-2007 Club Delphi