Silverlight 3 fuera del navegador

Una de las novedades que trae Silverlight 3 es que nos permite ejecutar aplicaciones Silverlight como aplicaciones de escritorio fuera del navegador.

Esto nos da el potencial de ejecutar nuestras aplicaciones Silverlight en modo offline.

Los pasos que debemos seguir conseguir esto son los siguientes:

  1. Creamos un nuevo proyecto de tipo Silverlight. Asumiremos que tenemos instalado todo lo necesario para el desarrollo de aplicaciones Silverlight 3. Ver página oficial.image_thumb7
  2. Una vez creado el proyecto llamado en nuestro caso “FueraBrowser”, desarrollamos nuestra aplicación tal y como queremos. Para este ejemplo simplemente añadiremos un botón que lanza un mensaje cuando hacemos click sobre él.image12
  3. Abrimos el fichero AppManifest.xml e insertamos el código que se muestra a continuación. El elemento EntryPointAssembly indica el nombre del assembly que coincide con el nombre de la aplicación, el elemento EntryPointType es la clase que carga la aplicación. A parte podemos configurar el ShortName que será el nombre que se muestra en el icono del escritorio, el Title que se corresponde con el titulo de la ventana que mostrará la aplicación y finalmente del Blurb testo que se verá en la sección de “Comments”:
    <Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      EntryPointAssembly="FueraBrowser"
      EntryPointType="FueraBrowser.App">
      <Deployment.Parts>
      </Deployment.Parts>
      <Deployment.OutOfBrowserSettings>
        <OutOfBrowserSettings
          ShortName="Fuera del browser">
          <OutOfBrowserSettings.WindowSettings>
            <WindowSettings Title="Offline Fuera del browser" />
          </OutOfBrowserSettings.WindowSettings>
          <OutOfBrowserSettings.Blurb>
            Permite guardar tus tareas cuando estas offline
          </OutOfBrowserSettings.Blurb>
        </OutOfBrowserSettings>
      </Deployment.OutOfBrowserSettings>
    </Deployment>

  4. Ejecutamos la aplicación y sobre la misma, al pulsar el botón derecho del ratón nos aparecerá un menú contextual como el siguiente, que nos permite instalar la aplicación en nuestro ordenador:image_thumb34
  5. Si pulsamos “Instalar Fuera del browser en este equipo…” nos aparecerá un cuadro de instalación en que se nos da la opción de colocar el acceso directo en el Menú Inicio o en el Escritorio.image_thumb33
  6. Si pulsamos “Aceptar” finalizará la instalación y aparecerá nuestra aplicación desarrollada en Silverlight 3 pero ejecutada como una aplicación de escritorio:               image_thumb31
  7. En el menú inicio tendremos un acceso directo a la aplicación:image_thumb38
  8. Para desinstalar nuestra aplicación simplemente debemos pulsar el botón derecho del ratón sobre la aplicación y pulsar “Quitar esta aplicación…” en el menú contextual que aparecerá como se muestra a continuación:                                      image_thumb37 

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

Marquee hecho en Silverlight

En la cabecera de mi blog, he insertado un Marquee que he desarrollado en Silverlight. Dicho Marquee muestra los titulares de los post publicados en el blog para facilitar el acceso a ellos.

Lector RSS en Silverlight para LaBloguera

Os habréis dado cuenta que el pasado lunes 24 de Agosto desapareció el lector RSS de noticias del portal de Geeks que habíamos situado en la portada de LaBloguera. Esto ha sido debido a que el lector que le propuse poner a Cesar Reneses en portada, lo desarrollé con el servicio de Popfly. Y dicho servicio fué retirado el pasado lunes. Para más información ver este blog.

Tras todo esto hemos pensamos desarrollar otro lector en Silverlight para sustituir al anterior, el cual estoy desarrollando ahora mismo.

Os hago un adelanto de cómo será el lector de RSS que insertaremos en la portada de LaBloguera.

Reversi en Silverlight. Party Quijote 2009

El viernes pasado día 17/07/2009 aprovechando el viaje a la Party Quijote impartí un taller junto a mi compañero César Reneses titulado “Silverlight: Las aplicaciones en la Web”.

Tras una pequeña introducción a la tecnología Silverlight, mostramos cómo crear una aplicación web Silverlight. Para ello decidimos realizar el juego del Reversi o también conocido como Othello.

Dejo un enlace donde podemos encontrar el juego desarrollado con capacidad de jugar contra la máquina. Ver Reversi Silverlight.

image

O3D: Google 3D. Impresionante

Esta gente de Google está preparando lo que puede ser la revolución de las aplicaciones en la web, aplicaciones 3D en el browser.

O3D es una API open-source en JavaScript para la creación de aplicaciones graficas 3D interactivas que se ejecutan sobre nuestro navegador. Haciendo uso de todos los recursos de nuestras tarjetas graficas.

Os dejo  un enlace a la página del proyecto O3D Google.

Algunos ejemplos:

http://o3d.googlecode.com/svn/trunk/samples/beachdemo/beachdemo.html

http://o3d.googlecode.com/svn/trunk/samples/pingpong/o3dPingPong.html

http://o3d.googlecode.com/svn/trunk/samples/io/io.html

Y muchos más…

Manejando el navegador con una única instancia

En los últimos días se me ha planteado la necesidad de trabajar con el navegador web pero no incrustado dentro de nuestra aplicación sino de forma externa a ella. Además me interesaba trabajar con una única instancia del navegador de forma que cada vez que se quisiese visualizar una página nueva se recargase la instancia activa en ese momento.

El primer planteamiento que hice fue el siguiente:

using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace ManejandoNavegador
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonGo_Click(object sender, EventArgs e)
        {
            Process.Start(“IEXPLORE.EXE”, textBoxURL.Text);
        }

     }

}

Con esta solución cada vez que se visualizaba una página se lanzaba una nueva instancia del navegador, por lo tanto fue descartada.

Una segunda solución planteada es la que se muestra a continuación:

using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace ManejandoNavegador
{
    public partial class Form1 : Form
    {
        Process navegador;
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonGo_Click(object sender, EventArgs e)
        {
            if (navegador!=null)
            {
                navegador.Kill();
            }
            navegador= Process.Start(“IEXPLORE.EXE”, textBoxURL.Text);
        }

     }

}

Con esta solución conseguimos que solo haya una instancia del navegador gracias a que cada vez que lanzamos una instancia nueva se cierra la instancia anterior. Esto provoca cierto parpadeo al cerrar una instancia y lanzar otra nueva. Esto hizo que se descartara también esta ultima solución.

Finalmente decidí utilizar la siguiente solución añadiendo la referencia al COM Microsoft Internet Controls y añadiendo el “using SHDocVw”:

using System;
using System.Windows.Forms;
using System.Diagnostics;
using SHDocVw;

namespace ManejandoNavegador
{
    public partial class Form1 : Form
    {
        InternetExplorer explorer;
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonGo_Click(object sender, EventArgs e)
        {
            if (explorer==null)
            {
                explorer= new InternetExplorer();
                explorer.Visible = true;
            }
            object Emtry = 0;
            explorer.Navigate(textBoxURL.Text, ref Emtry, ref Emtry, ref Emtry, ref Emtry);
        }
    }
}

De este modo se consiguió visualizar las páginas deseadas sobre una misma instancia del navegador. El usuario simplemente apreciará que la página se recarga con cada página nueva.

Trabajando con Sockets

Últimamente ando liado con una aplicación cliente-servidor que requiere una comunicación en tiempo real del cliente con el servidor. Para agilizar esta comunicación pensé en utilizar sockets y aquí os paso un ejemplo de una simple aplicación tanto del lado del cliente como del lado del servidor.

Del lado del servidor necesitamos quedar a la espera, en un puerto libre que no esté reservado por el sistema, de una petición de conexión del cliente. Una vez que el cliente realice una conexión con el servidor, se estable un socket entre ambos por el cual se puede transferir la información que sea necesaria.

Código del lado del servidor:

using System;
using System.Net.Sockets;
using System.IO;

namespace ConsoleApplicationSocketServer
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Puerto donde escuchará la aplicación servidora
            int puerto=10;

            Console.WriteLine("Servidor lanzado. Esperando conexión del cliente…");

            //Se abre un puerto de escucha.
            TcpListener tcpListener = new TcpListener(puerto);
            tcpListener.Start();

            //El Servidor espera a que se conecte el cliente.
            Socket socketForClient = tcpListener.AcceptSocket();

            if (socketForClient.Connected)
            {
                Console.WriteLine("Cliente conectado correctamente.");

                //Stream por donde se recibirá y enviará información al cliente.
                NetworkStream networkstream = new NetworkStream(socketForClient);

                StreamWriter streamWriter = new StreamWriter(networkstream);

                StreamReader streamReader = new StreamReader(networkstream);

                string dato = "Dato enviado desde el servidor";

                //Enviamos información al cliente.
                streamWriter.WriteLine(dato);
                Console.WriteLine("Dato enviado al cliente");
                streamWriter.Flush();

                //Recibimos información del cliente.
                dato = streamReader.ReadLine();
                Console.WriteLine(dato);

                //Cerramos los recursos abiertos.
                streamWriter.Close();
                streamReader.Close();
                networkstream.Close();
            }

            //Cerramos el socket con el cliente.
            socketForClient.Close();
            Console.WriteLine("Cerrando aplicación. Pulse una tecla para finalizar");
            Console.ReadKey();
        }
    }
}

En la parte del cliente simplemente necesitamos realizar una conexión con el servidor estableciendo el host y puerto donde está hospedada la aplicación servidora. A partir de ahí simplemente utilizaremos el socket creado para enviar y recibir información del servidor.

Código del lado del cliente:

using System;
using System.Net.Sockets;
using System.IO;

namespace ConsoleApplicationSocketCliente
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Puerto del servidor.
            int puerto = 10;
            //Host del servidor.
            string host = "localhost";

            TcpClient socketForServer;

            try
            {
                //Establecemos socket con el servidor.
                socketForServer = new TcpClient(host, puerto);
            }
            catch
            {

                Console.WriteLine("Error conectando con el servidor {0}. Pulse una tecla para finalizar…",host);
                Console.ReadKey();
                return;
            }

            //Flujo de envio y recepción de datos al servidor
            NetworkStream networkStream = socketForServer.GetStream();
            //Para escribir datos en el flujo.
            StreamWriter streamWriter = new StreamWriter(networkStream);
            //Para leer datos del flujo.
            StreamReader streamReader = new StreamReader(networkStream);

            try
            {
                string dato;
                //Recibimos damos del servidor.
                dato = streamReader.ReadLine();
                Console.WriteLine(dato);
                //Enviamos datos al servidor
                streamWriter.WriteLine("Mensaje recibido en el cliente");
                streamWriter.Flush();
            }
            catch
            {
                Console.WriteLine("Error recibiendo del servidor. Pulse una tecla para finalizar…");
                Console.ReadKey();
            }

            //Cerramos los recursos abiertos.
            streamReader.Close();
            streamWriter.Close();
            networkStream.Close();

            Console.ReadKey();

        }
    }
}

La consola de salida de la aplicación servidora sería la siguiente:

image

La consola de salida de la aplicación cliente sería la siguiente:

image

Impresora PDF por e-mail

De casualidad me encontré por ahi una nueva forma de sacarle partido a los correos electrónicos.


A más de uno nos habrá pasado que tenemos un fichero y queremos convertirlo en formato PDF y no tenemos a mano ninguna herramienta que nos los convierta.


Pues simplemente necesitas tener en tu lista de contactos estas direcciones que te sacaran de algun que otro apuro }:-)


  1. pdf@koolwire.com: Si envías un correo a esta dirección, te devuelve el adjunto convertido en pdf.
  2. pdf2txt@adobe.com: El archivo pdf ajunto enviado a esta dirección se te devuelve como texto plano.

Invocar métodos dinámicamente conocidos en tiempo de ejecución

    La mayoria de ocasiones sabremos qué métodos invocar antes de la compilación, por lo tanto, podemos invocar directamente al método con sus parámetros, pero habrá ocasiones en las que esto no sea así y necesitemos invocarlos dinámicamente en tiempo de ejecuación.


    Por ejemplo, imaginemos que tenemos una clase llamada Calculadora que contiene un método para cada tipo de operación (Suma, Resta, Multiplicacion y Division) y solo sabremos durante la ejecución de nuestro programa el método que tenemos que llamar. ¿Qué harias si en un momento necesitamos ejecutar el método Suma con los parámetros 2 y 3, sabiendo unicamente el string “Suma” y el int 2 y 3 ?


    Este problema lo podemos solucinar utilizando el espacio de nombres Reflection, mediante el uso del método InvokeMember en el objeto Type.


    El método InvokeMember acepta los siguientes parámetros: nombre del método a invocar, una seria de flags de invocación, un atributo con una seria de propiedades de la misma, el objeto sobre el que se realiza la invocación y un arraya de object que contienen los parámetros del método. Para más información de los parámetros ver aquí.


    Un ejemplo seria el siguiente:



string metodo = Console.ReadLine(); //Recogemos por teclado el nombre del método a ejecutar.


int op1 = Convert.ToInt32(Console.ReadLine()); //Recogemos el primer operando


int op2 = Convert.ToInt32(Console.ReadLine()); //Recogemos el segundo operando


Type tipoObjeto = typeof(Calculadora); //Obtenemos el tipo del objeto calculadora.


object[] parametros = new object[] { op1, op2 };


int resultado = (int)tipoObjeto.InvokeMember(metodo, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, pedroCalculadora, parametros);


Console.WriteLine(resultado); //Imprimimos por pantalla el resultado


 


      Del mismo modo podemos trabajar con las propiedades de un objeto, simplemente llamaremos al método GetProperty el cual acepta como parámetro el nombre de la propiedad y nos retorna un PropertyInfo a y con este objeto ya podemos acceder al metodo get de esta propiedad. Como mejor lo veremos es con un ejemplo. Imaginemos que en la clase Calcualdora del ejemplo anterior tenemos una propiedad para el nombre llamada Nombre y queremos acceder al Get de la misma en ejecuación simplemente conociendo el nombre de la propiedad:


 



Type tipoObjeto = typeof(Calculadora); //Obtenemos el tipo del objeto calculadora.


PropertyInfo propiedadInfo= tipoObjeto.GetProperty(“Nombre”);//Obtenemos la propiedad que queremos.


MethodInfo metodoInfo = propiedadInfo.GetGetMethod();//Obtenemos el método de la propiedad.


string resultado = (string)metodoInfo.Invoke(pedroCalculadora, new object[0]);


Console.WriteLine(resultado); //Imprimimos por pantalla el resultado


 


El resultado será el nombre de la calculadora y lo hemos obtenido conociendo el nombre de la propiedad.

Jugando con la información de los XML´s —> xsd.exe (Parte 2)

En el post anterior comentamos cómo deserializar un fichero XML para obtener una serie de instancias de unas clases que lo representan. 


Ahora vamos a realizar lo contrario, a partir de una instancia de la clase Libro, vamos a generar un XML asociado que se ajusta al esquema.


 


Nos creamos un objeto de la clase libro y le añadimos la información del libro a través de las propiedades de la clase que se proporcionan. A continuación con creamos un fichero con la clase FileStream y posteriormente con la clase XmlSerializer serializamos el objeto de la clase Libro que nos hemos creado anteriormente.


 


 




static void Main(string[] args)


{


    Libro milibro = new Libro();


 


    milibro.precio = (double)30;


    milibro.precioSpecified = true;


    milibro.Titulo = “Los tres cerditos”;


    milibro.Autores = new string[] {“Luis”,“Manolo”,“Laura” };


    milibro.Editorial = “MiEditorial”;


 


    FileStream fs = new FileStream(“prueba.xml”, FileMode.Create);


    XmlSerializer xs = new XmlSerializer(typeof(Libro));


    xs.Serialize(fs, milibro);


    fs.Close();


}


Nota:  Si nos fijamos en la clase Libro que se ha generado podemos ver como para el atributo precio hay un atributo en la clase que representa al mismo y otro de tipo boleano asociado. Esto se debe a que para los elementos que pueden o no aparecer (minOccurs=0) o para el caso de los atributos, que nunca son obligatorios, debemos indicar si queremos que se serialicen o no. Para ello en este caso indicamos que precioSpecified=true.


 


El resultado del ejemplo anterior seria el siguiente documento XML:


 




<?xml version=1.0?>


<Libro xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd=http://www.w3.org/2001/XMLSchema precio=30>


 


  <Titulo>Los tres cerditos</Titulo>


  <Autores>Luis</Autores>


  <Autores>Manolo</Autores>


  <Autores>Laura</Autores>


  <Editorial>MiEditorial</Editorial>


</Libro>


 


Y esto ha sido todo para serializar y deserializar objetos en ficheros XML.