viernes, octubre 16, 2009

Exportar Microsoft Project día por día versión Office 2007 Español

Hace varios años publique un post sobre Exportar Microsoft Project día por día basado en Office 2003.

Este post es creado en respuesta a todos aquellos que me pidieron actualizar la macro para la versión 2007 de Office.

Cambios en las referencias

References Esta es la principal diferencia con la versión Office 2003.

Cambios en el formulario de exportación

frmTimeScaled

Aproveché y modifiqué el formulario para que Start Date sea la fecha de inicio configurada en el proyecto y End Date sea la fecha actual.

Descarga y tutorial de uso

Ya pueden descargar el archivos de Project 2007 con la macro para Exportar Microsoft Project día por día versión Office 2007. El mismo archivo explica como instalarla y utilizarla.

Para más datos y explicaciones técnicas pueden ver el post de la versión original.

martes, septiembre 15, 2009

Mantener viva una aplicación .NET en IIS con Web Scheduler Tasks

Web Scheduled Tasks en ASP.NET nos sirve para ejecutar tareas programadas cada determinado intervalo de tiempo. Está pensado para Aplicaciones Web alojadas en Hostings que no nos permiten acceder al servidor.

Pero para asegurarnos de que las tareas se ejecuten, debemos mantener “viva” la aplicación. Este se convierte entonces en la primer tarea a configurar en Web Scheduled Tasks.

WebRequestTask para Web Scheduled Tasks

Actualicé el sitio demo de Web Scheduled Tasks para incorporar un objeto IScheduleable cuya misión es mantener viva una aplicación a través de un WebRequest.

El código es muy sencillo y es el siguiente:

WebRequestTask

Lo que hace es tomar todas las entradas del Web.config cuyo “name” comience con “webRequest” y hace un request a la URL indicada en “value”. El sitio demo tiene la siguiente entrada en el Web.config:

<add key="webRequest01" value="http://localhost:38652/DemoScheduler/Default.aspx" />

Deberán modificar la URL. En mi PC, el sitio está en el puerto 38652, si el puerto es 80 no hay necesidad de indicarlo.

lunes, septiembre 14, 2009

Web Scheduled Tasks en ASP.NET 2.0, 3.0, 3.5 y MVC

¿Cómo hacer para automatizar tareas en nuestro sitio Web si no tenemos acceso al servidor ni a los Scheduled Tasks?

Omar Al Zabir nos ofrece una solución muy creativa: utilizar el evento que genera un objeto al ser removido del caché. Aquí la solución de Omar.

Tomando la solución propuesta pero intentando convertirla en lo más portable y menos invasiva posible desarrolle el Web Scheduled Tasks para ASP.NET 2.0 o superior. Funciona también con MVC.

Cómo funciona Web Scheduled Tasks

Web Scheduled Tasks se inicia en el Application_Start del global.asax y crea una lista de objetos IScheduleable obteniendo los datos del web.config.

En el web.config se indica cada cuanto tiempo el Web Scheduled Tasks llamará a las tareas y lo único que les proveerá son los objetos Application y Cache ya que de otra forma no estarían disponibles. El Resto depende de la tarea: cuando ejecutarse, cómo controlar si ya se está ejecutando, log de errores, etc.

Las tareas se ejecutarán en un thread que no estará vinculado con un request de un usuario por lo que no se puede utilizar cosas como HttpContext.Current o Server.MapPath.

Implementar Web Scheduled Tasks en 4 pasos

Paso 1: copiar  WebScheduledTasks.dll en la carpeta BIN de nuestra Aplicación Web.

Paso 2: crear las clases que implementen IScheduleable. La interfaz es muy sencilla con un método y dos propiedades.

IScheduleable

El método Run recibe el objeto Application y el objeto Cache ya que de otra forma serían inaccesibles.

Paso 3: configurar Web Scheduled Tasks a través del web.config. Para hacer esto utilicé el muy buen tutorial Creating Custom Configuration Sections in Web.config using .NET 2.0.

Son dos bloques. El primero hay que agregarlo dentro de <configSections> y define la nueva sección del Web.config y la clase que lo controla. El segundo va dentro de <configuration> y son los settings propios de Web Secheduled Tasks. El primer seteo es el intervalo que define cada cuantos minutos el sistema revisará las tareas para ejecutarlas.

web.config

Dentro de <tasks> están definidos los objetos que deben ejecutarse periódicamente. Debe colocarse el AssemblyQualifiedName, de otra forma no sabrá como instanciarlo. El AssemblyQualifiedName de mi tarea de ejemplo es "ActualizaHoraTask, App_Code.owmojsxy, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null". Si no saben como armarlo, pueden ejecutar esto: Response.Write((new Objeto()).GetType.AssemblyQualifiedName).

Paso 4: modificar el Global.asax. Simplemente debemos agregar la siguiente línea al evento Application_Start: bd.WebScheduledTasks.Scheduler.RunTimer();

globalasax

Cómo saber el estado de Web Scheduled Tasks

Scheduler expone la propiedad “Status” que devuelve un XML con el estado de Web Scheduled Tasks y las tareas.

En en XML se puede ver:

  • StartTime: fecha y hora en que se inicializó Web Scheduled Tasks
  • Interval: definido en el Web.config
  • LastTickTime: hora a la que se ejecutó por última vez
  • CacheTimerExist: muestra si existe el objeto en Cache que permite que todo funcione.
  • LastError: en “object” veremos el objeto que generó el último error y en “error” su descripción.
  • ScheduledTasks: veremos la lista de los objetos que invocará el sistema.

Web Scheduled Tasks Status

Además de Status, Scheduler expone el método “ScheduleTick” que nos permite, tal vez desde algún administrador, ejecutar las tareas programadas manualmente. En realidad lo que lograremos es “despertar” a Web Scheduled Tasks para que revise cuales tareas deben ser ejecutadas.

Descargar Web Scheduled Tasks

Pueden descargar:

Espero que les sea útil. Cualquier sugerencia, corrección, o aporte será más que bienvenido.

lunes, septiembre 07, 2009

Includes en ASP.NET MVC

De pronto me surgió la necesidad de usar INCLUDES en el sitio que estoy creando en ASP.NET y MVC. Como siempre fui a Google pero esta vez no encontré ninguna respuesta satisfactoria (alguno recomendó hacer un Html helper para leer el contenido de un archivo).

Alguien podría preguntar cual es la necesidad de usar Includes teniendo tantas otras alternativas. En mi caso, tengo un proceso que genera HTMLs estáticos y necesito mostrarlos en una "caja" en el sitio.

Luego de algunas pruebas, estas son las mejores formas, según mi criterio, de usar Includes en ASP.NET y MVC.

Los includes tradicionales siguen funcionando

En principio los Includes tradicionales de ASP siguen funcionando, de modo que podemos usar:
<!--#include virtual="/includes/pagina.htm"-->
para incluír un html a partir del root. También podemos usar
<!--#include virtual="../includes/pagina.htm"-->
para incluir un html en forma relativa a donde "estamos parados".

Esto funciona incluso si el TAG Include se encuentra dentro de un Partial View. El inconveniente es el de siempre: no podemos usar variables para definir cual archivos queremos incluir. Es decir, no podemos hacer esto:
<!--#include virtual="../includes/<%= nombreArchivo %>"-->
ya que el TAG include se interpretará antes que ASP.NET (aún con MVC donde todo pasa por ASP.NET).

Includes dinámicos

La forma que encontré para lograr "Includes dinámicos" es usar la sentencia
Html.RenderPartial("PartialView")
La única restricción es que el archivo debe tener extensión .ascx (o aspx) pero no necesita la cabecera que lo define como Partial View si guardamos el archivo en la carpeta /Views/Shared. Es decir, podemos tomar una HTML, le cambiamos la extensión y lo incluimos con Html.RenderPartial.

En mi caso, el proceso que genera el HTML, ahora lo graba a disco con la extensión .ascx

domingo, marzo 29, 2009

Mostrar AdSense sólo cuando el usuario viene de Google en ASP.NET

Es bastante común hoy en día encontrarnos con sitios que muestran publicidad de AdSense sólo a los usuarios que llegan a través de Google.

Por eso se me ocurrió hacer esto mismo pero de la forma más sencilla posible. Nada de estilo refinado en este caso, simplemente lo más fácil de implementar.

Así nació este User WebControl llamado refererAdSense contenido todo en un solo archivo .ascx. Seguramente el código puede ser mejorado o escrito con un poco más de estilo, sin embargo esto es lo que hice:

El WebControl comienza con una propiedad “AdPosition” que usaremos para identificar el código de AdSense que se debe mostrar. Un método booleano “UserFromGoogle” que devuelve true si encuentra la cadena “.google.” en el referer del request.

Por último, un simple SWITCH donde pondremos todos los códigos AdSense de nuestro sitio.

Para poder usar este User WebControl, simplemente lo copiamos en una carpeta (por ejemplo “/controls”) y, donde queremos la publicidad ponemos el tag “register” al principio de la página:

<%@ Register Src="~/controls/refererAdSense.ascx" TagName="refererAdSense" TagPrefix="rad" %>

Y finalmente ponemos el TAG correspondiente donde queremos la publicidad de AdSense:

<rad:refererAdSense AdPosition="topBanner" runat="server" />

Como valor de la propiedad “AdPosition” ponemos el nombre que identifica al bloque de AdSense del archivo .ascx.

Les dejo el refererAdSense.asxc para que lo bajen.

miércoles, febrero 04, 2009

Simulando streaming de video Flash FLV con ASP.NET

Esta solución permite reproducir video Flash FLV tal como lo hace YouTube.com de forma que podemos adelantar el video aún cuando no se haya descargado la parte que queremos ver.

La verdadera solución se encuentra en kfra de donde podremos descargar la solución tanto para .NET 1.1 como 2.0.

Pero para los que no podemos hacer modificaciones en el servidor IIS o (como yo) son amantes de las soluciones sencillas, no intrusivas y contenidas en una sola página es que armé esta versión.

Se trata de una página ASPX llamada getFlv.aspx que simplemente copiamos en nuestro sitio web e invocamos desde Flash con 2 parametros:
- v: para el nombre del video. Si comienza con “/” será el path relativo al root del sitio. Si no comienza con “/” buscará a partir del lugar donde se encuentre esta página.
- start: para indicar el byte a partir del cual quieren reproducir el video. Si no le pasamos nada, entonces devolverá el video completo.

Ejemplos:
  • http://misitio.dominio.com/videos/getFlv.aspx?v=video.flv (simplemente traerá el video ubicado en la mísma carpeta que getFlv.aspx)
  • http://misitio.dominio.com/videos/getFlv.aspx?v=/video.flv (traerá el video desde el root del sitio)
  • http://misitio.dominio.com/videos/getFlv.aspx?v=nuevos/video.flv&start=580014 (traerá el video desde la carpeta "nuevos" ubicada en la misma carpeta que getFlv.aspx y lo entregará a partir del byte 580014)
Hay que tener en cuenta que esta página ASPX lo único que hace es devolver el video FLV a partir del byte indicado por parámetro. El resto dependerá del player.

En la el mismo post de kfra hay un player que pueden usar, pero si quieren desarrollar uno ustedes, deberán tener en cuenta que, para poder reproducir el video, deben pasar un start que coincida con un Key Frame. Para esto deben buscar en la metadata del streaming donde encontrarán dos arrays, Times y FilePositions. No todos los FLV contienen esta metadata y en estos casos deberán usar alguna aplicación para agregarla.

Aquí les dejo el link a getFlv.aspx.

Por supuesto que todo el crédito es de kfra. Yo sólo hice uso de la programación orientada al copy-paste.

Saludos