Controlar la salida de un programa

Controlar la salida de un programa

Postby Andrés González » Thu Apr 28, 2011 8:30 am

He creado una dbf que controla los accesos a los programas. Cuando supero el password de acceso me lo registra en accesos.dbf mediante la función InicioAcceso() y cuando hago alt-F4, Salir del Menu o la crucecita de exit de la ventana, me registra la fecha y la hora de abandono del programa mediante la función FinalizoAcceso(), pero cuando es el sistema que cierra el programa con el boton apagar sistema del inicio de windows sencillamente me cierra el programa sin anotar nada. Alguien sabe si existe alguna forma de controlar que también me ejecute la función de FinalizarAcceso() cuando es apagado el programa por el sistema. Esta función es la ultima que se ejecuta despues de cerrar la ventana principal del programa y por tanto cuando se cierra por el sistema no se llega a ejecutar. Alguna pista?
Saludos

Andrés González desde Mallorca
User avatar
Andrés González
 
Posts: 627
Joined: Thu Jan 19, 2006 10:45 am
Location: Mallorca

Re: Controlar la salida de un programa

Postby Carles » Thu Apr 28, 2011 9:46 am

A,

Prueba
Code: Select all  Expand view
EXIT PROCEDURE MiFuncion()
...
RETU NIL
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1101
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona

Re: Controlar la salida de un programa

Postby Andrés González » Mon May 02, 2011 6:12 am

Perdona Carles he estado liado estos dias y no había entrado en el foro. Lo pruebo a lo largo de la mañana gracias.
Saludos

Andrés González desde Mallorca
User avatar
Andrés González
 
Posts: 627
Joined: Thu Jan 19, 2006 10:45 am
Location: Mallorca

Re: Controlar la salida de un programa

Postby Andrés González » Tue May 03, 2011 10:58 am

Carles, donde encuentro información de EXIT PROCEDURE. Se comporta raro ya que me desaparecen todas las variables y no puedo actualizar la base de datos con variables private que se ven en todos los modulos. Lo que quiero hacer es que cuando se sale del programa es actualizar los datos del ultimo usuario, la fecha y la hora. Pero estos datos me han desaparecido cuando entro en exit procedure, no así si la mantengo como función, pero si cierran el programa por ejemplo con el administrador de tareas no me registra esos datos.
Saludos

Andrés González desde Mallorca
User avatar
Andrés González
 
Posts: 627
Joined: Thu Jan 19, 2006 10:45 am
Location: Mallorca

Re: Controlar la salida de un programa

Postby Carles » Wed May 04, 2011 7:34 am

A,

Basicamente, esta sentencia se ejecuta justo antes de la salida del programa. Desde dentro del procedimiento puedes ejecutar el codigo que quieras y acceder a todas tus variables VISIBLES desde él.

Esta es la explicación teórica de las NG

Code: Select all  Expand view
EXIT PROCEDURE
Declara un procedimiento de clausura
─────────────────────────────────────────────────────────────────────────
Sintaxis

    EXIT PROCEDURE <idProcedimiento>
       [FIELD <lista idCampo> [IN <idAlias>]]
       [LOCAL <identificador> [[:= <inicializador>]]]
       [MEMVAR <lista identificador>]
       .
       . <sentencias ejecutables>
       .
       [RETURN]

Argumentos

    EXIT PROCEDURE declara un procedimiento que se ejecuta en la
    terminación del programa.

    <idProcedimiento> es el nombre del procedimiento de clausura que se
    va a declarar. Los nombres de procedimientos de clausura pueden tener
    cualquier longitud, pero sólo son significativos los primeros 10
    caracteres. Los nombres no deben comenzar con un signo de subrayado,
    pero pueden contener cualquier combinación de caracteres, números o
    signos de subrayado.

Descripción

    La sentencia EXIT PROCEDURE declara un procedimiento que se ejecutará
    cuando finalice el programa. Los procedimientos de clausura se llaman
    después de que se haya completado la última sentencia ejecutable en una
    aplicación de CA-Clipper. Las sentencias EXIT PROCEDURE pueden
    utilizarse para ejecutar tareas de mantenimiento habituales, como por
    ejemplo, guardar los parámetros de configuración en un fichero, cerrar
    un fichero de registro o concluir una sesión de comunicaciones.

    La visibilidad de los procedimientos de clausura está limitada al
    sistema; por lo tanto, no es posible llamar a un procedimiento de
    clausura desde un procedimiento o función definido por el usuario. Los
    procedimientos de clausura no reciben parámetros.

    Una vez que se ha completado la última sentencia ejecutable, el control
    pasa de un procedimiento de clausura al siguiente hasta que se ha
    llamado a todos los procedimientos de la lista de clausura. El control
    pasa seguidamente al sistema operativo.
    fuente (.prg). Una vez declarado, se hace referencia a las sentencias
    EXIT PROCEDURE con este identificador de módulo. Una aplicación puede
    utilizar cualquier número de procedimientos de clausura, solicitando de
    forma explícita mediante REQUEST sus identificadores de módulo.

    Los procedimientos de clausura solicitados para una aplicación se
    mencionan, de forma colectiva, como la lista de clausura. No existe un
    orden de ejecución obligatorio de procedimientos en la lista de
    clausura; sin embargo, si un procedimiento de clausura se declara en el
    mismo módulo fuente (.prg) que la rutina principal o raíz, éste será el
    primer procedimiento de clausura llamado.

    La terminación de una aplicación de CA-Clipper dada puede atribuirse a
    alguna de las siguientes causas:

    ■  RETURN desde la rutina principal o raíz

    ■  el mandato QUIT

    ■  la ejecución de un BREAK sin incluir BEGIN SEQUENCE...END
    La sentencia ANNOUNCE declara un identificador de módulo para un módulo

    ■  error irrecuperable

    No se puede garantizar la ejecución de un procedimiento de clausura
    cuando el sistema detecta un error irrecuperable. Si se ha producido un
    error durante un procedimiento de clausura, el sistema vuelve al DOS.
    Los procedimientos de clausura pendientes no se llaman.

Ejemplos

    ■  En este ejemplo se ilustra la construcción de un mecanismo de
       temporización simple, utilizando INIT y EXIT PROCEDURE:

       // imprime la cantidad de tiempo necesario para,
       // leer, ordenar y mostrar una lista de nombres
       // de ficheros.

       ANNOUNCE MiSistema

       STATIC nInicio

       PROCEDURE Main()
          AEVAL( ASORT( DIRECTORY( "*.*" ) ),;
              { | aInfoFichero | QOUT( aInfoFichero[ 1 ] ) } )

          RETURN

       INIT PROCEDURE MiInicio()
          nInicio := SECONDS()
          RETURN

       EXIT PROCEDURE MiClausura()
          ?
          ? "Tiempo transcurrido: "
          ?? SECONDS() - nInicio
          RETURN


Si tu tienes una funcion montada de tal manera q puedas acceder al conjunto de sus variables desde otro modulo, no tendras problemas en realizar esta accion...
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1101
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona

Re: Controlar la salida de un programa

Postby Carles » Wed May 04, 2011 7:35 am

A,

Basicamente, esta sentencia se ejecuta justo antes de la salida del programa. Desde dentro del procedimiento puedes ejecutar el codigo que quieras y acceder a todas tus variables VISIBLES desde él.

Esta es la explicación teórica de las NG

Code: Select all  Expand view
EXIT PROCEDURE
Declara un procedimiento de clausura
─────────────────────────────────────────────────────────────────────────
Sintaxis

    EXIT PROCEDURE <idProcedimiento>
       [FIELD <lista idCampo> [IN <idAlias>]]
       [LOCAL <identificador> [[:= <inicializador>]]]
       [MEMVAR <lista identificador>]
       .
       . <sentencias ejecutables>
       .
       [RETURN]

Argumentos

    EXIT PROCEDURE declara un procedimiento que se ejecuta en la
    terminación del programa.

    <idProcedimiento> es el nombre del procedimiento de clausura que se
    va a declarar. Los nombres de procedimientos de clausura pueden tener
    cualquier longitud, pero sólo son significativos los primeros 10
    caracteres. Los nombres no deben comenzar con un signo de subrayado,
    pero pueden contener cualquier combinación de caracteres, números o
    signos de subrayado.

Descripción

    La sentencia EXIT PROCEDURE declara un procedimiento que se ejecutará
    cuando finalice el programa. Los procedimientos de clausura se llaman
    después de que se haya completado la última sentencia ejecutable en una
    aplicación de CA-Clipper. Las sentencias EXIT PROCEDURE pueden
    utilizarse para ejecutar tareas de mantenimiento habituales, como por
    ejemplo, guardar los parámetros de configuración en un fichero, cerrar
    un fichero de registro o concluir una sesión de comunicaciones.

    La visibilidad de los procedimientos de clausura está limitada al
    sistema; por lo tanto, no es posible llamar a un procedimiento de
    clausura desde un procedimiento o función definido por el usuario. Los
    procedimientos de clausura no reciben parámetros.

    Una vez que se ha completado la última sentencia ejecutable, el control
    pasa de un procedimiento de clausura al siguiente hasta que se ha
    llamado a todos los procedimientos de la lista de clausura. El control
    pasa seguidamente al sistema operativo.
    fuente (.prg). Una vez declarado, se hace referencia a las sentencias
    EXIT PROCEDURE con este identificador de módulo. Una aplicación puede
    utilizar cualquier número de procedimientos de clausura, solicitando de
    forma explícita mediante REQUEST sus identificadores de módulo.

    Los procedimientos de clausura solicitados para una aplicación se
    mencionan, de forma colectiva, como la lista de clausura. No existe un
    orden de ejecución obligatorio de procedimientos en la lista de
    clausura; sin embargo, si un procedimiento de clausura se declara en el
    mismo módulo fuente (.prg) que la rutina principal o raíz, éste será el
    primer procedimiento de clausura llamado.

    La terminación de una aplicación de CA-Clipper dada puede atribuirse a
    alguna de las siguientes causas:

    ■  RETURN desde la rutina principal o raíz

    ■  el mandato QUIT

    ■  la ejecución de un BREAK sin incluir BEGIN SEQUENCE...END
    La sentencia ANNOUNCE declara un identificador de módulo para un módulo

    ■  error irrecuperable

    No se puede garantizar la ejecución de un procedimiento de clausura
    cuando el sistema detecta un error irrecuperable. Si se ha producido un
    error durante un procedimiento de clausura, el sistema vuelve al DOS.
    Los procedimientos de clausura pendientes no se llaman.

Ejemplos

    ■  En este ejemplo se ilustra la construcción de un mecanismo de
       temporización simple, utilizando INIT y EXIT PROCEDURE:

       // imprime la cantidad de tiempo necesario para,
       // leer, ordenar y mostrar una lista de nombres
       // de ficheros.

       ANNOUNCE MiSistema

       STATIC nInicio

       PROCEDURE Main()
          AEVAL( ASORT( DIRECTORY( "*.*" ) ),;
              { | aInfoFichero | QOUT( aInfoFichero[ 1 ] ) } )

          RETURN

       INIT PROCEDURE MiInicio()
          nInicio := SECONDS()
          RETURN

       EXIT PROCEDURE MiClausura()
          ?
          ? "Tiempo transcurrido: "
          ?? SECONDS() - nInicio
          RETURN


Si tu tienes una funcion montada de tal manera q puedas acceder al conjunto de sus variables desde otro modulo, no tendras problemas en realizar esta accion...
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1101
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona

Re: Controlar la salida de un programa

Postby Andrés González » Wed May 04, 2011 10:11 am

Debo estar haciendo algo mal, puesto que con FUNCTION va bien y con EXIT PROCEDURE entra pero cuando utilizo las variables me las muestra en blanco. Lo reviso y te comento.

Gracias.
Saludos

Andrés González desde Mallorca
User avatar
Andrés González
 
Posts: 627
Joined: Thu Jan 19, 2006 10:45 am
Location: Mallorca

Re: Controlar la salida de un programa

Postby Carles » Wed May 04, 2011 10:41 am

Andreas,

Piensa q si quieres gestionar tus variables de una funcion desde la exit procedure, estas deben ser visibles o accesible de alguna manera. Podrias hacer algo as, pe.

Code: Select all  Expand view

Modulo x.prg
static aDat

FUNCTION MiProceso()
    aDat := Array(4)
    aDat[1] := ...
    aDat[2] := ...
    ....
RETU NIL

FUNCTION GetaDat()
RETU aDat

// Exit desde el mismo modulo
EXIT PROCEDURE Save()
    ...
RETU NIL
 


Si quieres acceder desde otro modulo
Code: Select all  Expand view
Modulo z.prg
EXIT PROCEDURE Save()
    LOCAL aDat := GetoDat()
    ...
RETU NIL


No se, quizas pueda servirte....
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Carles
 
Posts: 1101
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona

Re: Controlar la salida de un programa

Postby Andrés González » Thu May 05, 2011 8:43 am

Arreglado Carles, fue un fallo mio y como tu dices son visibles todas las variables definidas correctamente. Mi error era que pensaba que las tenia definidas como PRIVATE y en realidad se definian por ellas mismas y luego las pasaba por referencia, ahora este procedimiento se ejecuta siempre:


Code: Select all  Expand view
*******************************
function lGetPassword()

   local oDlg, oUser, oPass
   local nTries    := 0 //Nº de intentos que quiero permitir
   local lGo       := .f.
   
   PRIVATE x_user, x_pass //Antes esto no estaba y por eso no los podia ver

   x_user = UPPER(GETENV("USERNAME"))+ space(4)
   x_pass = space(10)


   DEFINE DIALOG oDlg ;
          FROM 5, 5 TO 20, 50 ;
          TITLE "Por favor identifiquese..."

   @ 1,   2 BITMAP oBmp FILENAME ".\..\Bmp\Pass.Bmp" OF oDlg NOBORDER
   @ 1,  10 SAY "GESTION DE PUERTAS" OF oDlg
   @ 4,   1 SAY "Nombre:" OF oDlg
   @ 5.3, 1 SAY "P. de Acceso:" OF oDlg
   @ 4,   8 GET oUser VAR x_user picture "@!" OF oDlg SIZE 50 , 10 VALID ( oImg:LoadImage( , "..\COMU\FOTOS\"+alltrim(x_user)+".jpg" ), oImg:Refresh(), .T. )
   @ 5.3, 8 GET oPass VAR x_pass picture "
@!" OF oDlg PASSWORD  SIZE 50 , 10
    @ 2,  14 IMAGE oImg FILE "
..\COMU\FOTOS\"+alltrim(x_user)+".jpg" SIZE 50, 60 ADJUST


   @ 4, 4 BUTTON "
&Continuar" OF oDlg ;
           ACTION ( nTries++,;
                   lGo := ComprueboAcceso( x_user, x_pass ) ,;
                   If( nTries > 2 .or. lGo, oDlg:End(),;
                   ( MsgAlert( "
Datos Incorrectos..."+ Chr(13) +"Intenta otra vez" ), oUser:SetFocus(), oPass:SetFocus() ) ) )

   oBmp:lTransparent = .t.  // Hago el bmp transparente

   ACTIVATE DIALOG oDlg CENTERED ON PAINT (  oPass:SetFocus()   )


   return lGo

  ********************************

  Function ComprueboAcceso( x_user, x_pass )

      //Abre la base de datos de usuarios para esta aplicación.
      if !op_base("
USR",.f.,1,1)
          return .f.
      endif

      locate all for x_user= USER->user
      if !found()
         MsgInfo("
Usuario no registrado")
            use
         Return .F.
      elseif x_pass != USER->pasw
            MsgInfo("
Palabra clave incorrecta")
                use
            Return .F.
      endif

      //Me desago de la base de datos abierta y retorno acceso correcto y tomo el nivel de acceso
      x_level = USER->level
      use
      InicioAcceso()
      return .t.


*********************************

Func InicioAcceso()

       if !op_base("
ACC",.f.,1,1,.f.,"ACCESOS")
          return .f.
      endif

        Select("
ACCESOS")
        if netapp(0)
            Replace PRG       with d_prg
            Replace FECHAINI  with date()
            Replace HORAINI   with time()
            Replace USER      with x_user
            Replace LOGON     with x_logon
            Replace ORDENADOR with x_ord
            commit
        endif
       
        clos_base("
ACC",1,.f.)

Return .t.


********************************************
EXIT PROCEDURE FinalizoAcceso()

    if !op_base("
ACC",.f.,1,1,.f.,"ACCESOS")
       return .f.
    endif
      Select("
ACCESOS")

      DBSetOrder(5)  
      seek alltrim(x_user) + d_Prg
      LOCATE FOR USER = alltrim(x_user) .and. PRG = d_prg .and. EMPTY(FECHAFIN)
      DO WHILE Found()
         if rlock()  
         Replace FECHAFIN with date()
         Replace HORAFIN  with time()
         commit
         
         endif
         skip
         LOCATE FOR USER = alltrim(x_user) .and. PRG = d_prg .and. EMPTY(FECHAFIN)
      enddo

      clos_base("
ACC",1,.f.)
Return .t.
Saludos

Andrés González desde Mallorca
User avatar
Andrés González
 
Posts: 627
Joined: Thu Jan 19, 2006 10:45 am
Location: Mallorca


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 56 guests