26 de junio de 2011

Planificar tareas

Artículo original: Scheduling Tasks
http://doughennig.blogspot.com/2007/04/scheduling-tasks.html
Autor: Doug Hennig
Traducido por: Ana María Bisbé York

Stonefield Query tiene hace algunos años un planificador de informes. Nosotros simplemente empleamos el Planificador de tareas de Windows para ejecutar Stonefield Query, con el nombre de los informes a ejecutar y dónde enviar las salidas como parámetros, según el plan deseado. Para comunicarnos con el Planificador de Tareas, utilizamos el TaskScheduler.DLL, escrito por Mark Pryor. Parece que el sitio de donde lo descargué ya no está activo, por lo que está incluido en la descarga que mencionaré luego.

Sin embargo, después de actualizar a Windows Vista, descubrí que no trabajaba el planificador. Investigando este problema, descubrí que Windows Vista incluye Planificador de Tareas 2.0, donde la DLL fue escrita para soportar el Planificador de Tareas 1.0, que tiene una interfaz completamente diferente. Por tanto, volvemos al pasado, a la pizarra de dibujo.

Afortunadamente, la documentación de MSDN sobre el Planificador de Tareas 2.0 tenía toneladas de detalles y muchos ejemplos escritos en VBScript, que son fácilmente convertibles a VFP. Debido a que aun necesito utilizar el Planificador de Tareas 1.0, con XP y los sistemas anteriores, decidí crear una clase base TaskScheduler y a partir de ella, unas subclases XP y Vista.

No voy a mostrar el código para estas clases porque es muy largo (se puede descargar desde la página Technical Papers de mi sitio Web); pero he aquí algunos ejemplos sobre lo fácil que son de utilizar estas clases para planificar tareas. Estos ejemplos corren en Vista, en su lugar, emplee XPTaskScheduler para Windows XP o anterior.
* Crear una tarea que se ejecute cada día a las 3:00 AM.

loSchedule = createobject('VistaTaskScheduler')
with loSchedule
  .TaskName = 'Nombre de mi tarea'
  .UserName = 'Nombre de usuario de Windows'
  .Password = 'Contraseña de Windows'
  .StartTime = {^2007-04-26 03:00:00}
  .EXEName = 'Ruta completa del EXE'
  .EXEParameters = 'Todos los parámetros a pasar'
  .ScheduleType = 1 && diario
  if not .CreateTask()
    messagebox(.ErrorMessage)
  endif not .CreateTask()
endwith

* Crear una tarea  que se ejecute Martes, Jueves y Sábados a las 3:00 AM
* cada dos semanas.

loSchedule = createobject('VistaTaskScheduler')
with loSchedule
  .TaskName = 'Nombre de mi tarea'
  .UserName = 'Nombre de usuario de Windows'
  .Password = 'Contraseña de Windows'
  .StartTime = {^2007-04-26 03:00:00}
  .EXEName = 'Ruta completa del EXE'
  .EXEParameters = 'Todos los parámetros a pasar'
  .ScheduleType = 2 && semanal
  .Interval = 2
  store .T. to .DaysOfWeek[3], .DaysOfWeek[5], .DaysOfWeek[7]
  if not .CreateTask()
    messagebox(.ErrorMessage)
  endif not .CreateTask()
endwith

* Crear una tarea mensual que corra los días 1ro y 15 de cada mes a las 3:00 AM

loSchedule = createobject('VistaTaskScheduler')
with loSchedule
  .TaskName = 'Nombre de mi tarea'
  .UserName = 'Nombre de usuario de Windows'
  .Password = 'Contraseña de Windows'
  .StartTime = {^2007-04-26 03:00:00}
  .EXEName = 'Ruta completa del EXE'
  .EXEParameters = 'Todos los parámetros a pasar'
  .ScheduleType = 3
  store .T. to .DaysOfMonth[1], .DaysOfMonth[15]
  .MonthsOfYear = .T. && inicializa los 12 elementos de la matriz en .T.
  if not .CreateTask()
    messagebox(.ErrorMessage)
  endif not .CreateTask()
endwith

22 de junio de 2011

Decodificar QR usando ZBar

Anteriormente, publiqué un artículo para crear un código QR usando la Api de Google.

Ahora intento ejemplificar la Lectura de un QR usando la aplicación ZBar que es Open Source, y contiene unos ejecutables dentro de la carpeta BIN que en particular utilizo para este ejemplo el zbarimg.exe

Para este ejemplo, se supone que previamente se tiene "copiada" en portapapeles el QR a decodificar, usando GDI+ lo almaceno en un archivo temporal para decodificarlo.

El código es el siguiente:
SET DEFAULT TO SYS(5)+ADDBS(SYS(2003))

* --- Creamos una imagen desde el portapapeles para validar el QR ---
* --- Código de Luis María Guayan, Gracias por tus aportaciones. ---
Do System.App
loBmp = _Screen.System.Drawing.Bitmap.FromClipboard()
IF ISNULL(loBmp)
  MESSAGEBOX("Debe copiar antes la imagen del CBB al portapapeles!!",16,"Lector QR")
  RETURN
ENDIF 
uidImagen = ADDBS(SYS(2023)) + SYS(2015)+".png"
loBmp.Save(uidImagen, _Screen.System.Drawing.Imaging.ImageFormat.Png)

* --- Creamos el comando de DOS para ejecutar ZBar excelente herramienta open source ---
* --- http://zbar.sourceforge.net/  ---
lpComando = SYS(5)+ADDBS(SYS(2003))+"ZBar\zbarimg.exe -D "+uidImagen+ " > "+uidImagen+".txt"
TEXT TO xBAT NOSHOW ADDITIVE TEXTMERGE PRETEXT 7
echo off
<<lpComando>>
ENDTEXT
uidBat = ADDBS(SYS(2023)) + SYS(2015) + [.bat]
STRTOFILE(xBAT,uidBat)
zCommando = uidBat
Ejecuta(zCommando, 0)
BorraArchivo(uidBat)

* --- Ahora cargamos el contenido del QR ---
cContenidoQR = "" 
IF FILE(uidImagen+".txt")
  cContenidoQR = FILETOSTR(uidImagen+".txt")
ENDIF 
BorraArchivo(uidImagen)
BorraArchivo(uidImagen+".txt")

* --- Lo mostramos a pantalla ---
Messagebox(IIF(EMPTY(cContenidoQR),"ERROR: No se pudo leer el QR",cContenidoQR),64,"Lector QR")

*---------------------------------------------------
FUNCTION BorraArchivo(pFile)
*---------------------------------------------------
* Esta funcion elimina el archivo indicado como parametro
* si es que existe en Disco
*---------------------------------------------------
  IF FILE(pFile)
    DELETE FILE (pFile)
  ENDIF 
ENDFUNC 
*---------------------------------------------------

*---------------------------------------------------
FUNCTION Ejecuta(cComando, iStatus)
*---------------------------------------------------
*!* Esta funcion ejecuta un comando de DOS indicado
*!* como primer parámetro, el segundo es el estilo
*!* de la ventana a utilizar, ver el sig. listado
*!* entEstiloVentana Descripción
*!* 0 Oculta la ventana y activa otra.
*!* 1 Activa y muestra una ventana. Si la ventana está minimizada o maximizada, el sistema la restaura con su posición y tamaño originales. 
*!*             Una aplicación debe especificar este indicador cuando muestre la ventana por primera vez.
*!* 2 Activa la ventana y la muestra minimizada.
*!* 3 Activa la ventana y la muestra maximizada.
*!* 4 Muestra una ventana con su tamaño y posición más recientes. La ventana activa permanece activa.
*!* 5 Activa la ventana y la muestra con su tamaño y posición actuales.
*!* 6 Minimiza la ventana especificada y activa la siguiente ventana de mayor nivel en orden Z.
*!* 7 Muestra la ventana minimizada. La ventana activa permanece activa.
*!* 8 Muestra la ventana en su estado actual. La ventana activa permanece activa.
*!* 9 Activa y muestra la ventana. Si la ventana está minimizada o maximizada, el sistema la restaura con su posición y tamaño originales. 
*!*             Una aplicación debe especificar este indicador cuando se restaure una ventana minimizada.
*!* 10 Establece el estado de presentación a partir del estado del programa que inició la aplicación.
*----------------------------------------------------
  TRY 
    oShell = createobject("WScript.Shell") 
    oShell.Run(cComando,iStatus,.T.) 
  CATCH TO xEcepcion
    lsErrorEcepcion = "No se pudo ejecutar: "+cComando+ " RS:"+TRANSFORM(xEcepcion.ErrorNo) + CHR(13)+CHR(10)+  "Mensaje: " + xEcepcion.Message
    Messagebox(lsErrorEcepcion,16,"Lector QR")
  FINALLY
    *  
  ENDTRY   
ENDFUNC
*----------------------------------------------------

Pueden descargar el ejemplo completo, con librerias y ejecutables adicionales desde aqui

Baltazar Moreno