MSDN Blogs
  • WarNov Developer Evangelist

    Efecto Navideño para blogs usando HTML5

    • 2 Comments

    Luego de implementar el citado evento en mi propio blog, he recibido muchas preguntas de cómo lo logré.

    image

    He aquí la respuesta:

    Este trabajo es basado en un algoritmo de Javascript para HTML5 creado por David Flanagan que se basa en generar un elemento canvas por cada copito de nieve bajando en el blog. Entonces cada copo de nieve se agrega al DOM y es animado usando posicionamiento a través de CSS. Sin embargo se puede mejor usar un solo canvas y animar los copos dentro de este tal como lo sugiere Giorgo Sardo, con el fin de ahorrar memoria. Esto sin embargo puede producir que se bloquee la interacción normal con la página… es así que lo mejor es poner el canvas en un background de menor prioridad (atrás del contenido) tal como lo pueden ver en mi blog.    

    Este es el JavaScript requerido:

    (function () {
    
        // Start Animation only if browser support <canvas>
        if (document.createElement('canvas').getContext) {
            if (document.readyState === 'complete')
                Snow();
            else
                window.addEventListener('DOMContentLoaded', Snow,
    false); } var deg = Math.PI / 180; //Degrees to radians var sqrt3_2 = Math.sqrt(3) / 2; //Height of an eq triangle var flakes = []; // Things that are dropping var scrollspeed = 64; // How often we animate things var snowspeed = 500; // How often we add a new snowflake var maxflakes = 20;//Max number of flakes to be added var rand = function (n) { return Math.floor(n *
    Math.random()); } var canvas, sky; var snowingTimer; var invalidateMeasure = false; function Snow() { canvas = document.createElement('canvas'); canvas.style.position = 'fixed'; canvas.style.top = '0px'; canvas.style.left = '0px'; canvas.style.zIndex = '0'; document.body.insertBefore(canvas,
    document.body.firstChild); sky = canvas.getContext('2d'); ResetCanvas(); snowingTimer = setInterval(createSnowflake,snowspeed); setInterval(moveSnowflakes, scrollspeed); window.addEventListener('resize', ResetCanvas, false); } function ResetCanvas() { invalidateMeasure = true; canvas.width = document.body.offsetWidth; canvas.height = window.innerHeight; sky.strokeStyle = '#0066CC'; sky.fillStyle = 'white'; } function drawFlake(x, y, size, order) { sky.save(); sky.translate(x, y); snowflake(order, 0, Math.floor(sqrt3_2 * y), size); sky.fill(); sky.stroke(); sky.restore(); } function snowflake(n, x, y, len) { sky.save(); // Save current transformation sky.beginPath(); sky.translate(x, y);
    // Translate to starting point sky.moveTo(0, 0); // Begin a new subpath there leg(n); // Draw the first leg of the fractal sky.rotate(-120 * deg);
    // Rotate 120 degrees anticlockwise leg(n); // Draw the second leg sky.rotate(-120 * deg); // Rotate again. leg(n); // Draw the final leg sky.closePath(); // Close the subpath sky.restore();
    // Restore original transformation // Draw a single leg of a level-n Koch snowflake. // Leaves the current point at the end of // the leg it has drawn and translates the coordinate // system so the current point is (0,0).
    // This means you // can easily call rotate() after drawing a leg.
    function leg(n) { sky.save(); // Save current transform if (n == 0) { // Non-recursive case: sky.lineTo(len, 0);// Just a horizontal line } else { // Recursive case: _ _ // draw 4 sub-legs like: \/ sky.scale(1 / 3, 1 / 3);
    // Sub-legs are 1/3rd size leg(n - 1);
    // Draw the first sub-leg sky.rotate(60 * deg);
    // Turn 60 degrees clockwise leg(n - 1);
    // Draw the second sub-leg sky.rotate(-120 * deg);
    // Rotate 120 degrees back leg(n - 1); // Third sub-leg sky.rotate(60 * deg);
    // Back to original heading leg(n - 1); // Final sub-leg } sky.restore(); // Restore the transform sky.translate(len, 0);// Translate to end of leg } } function createSnowflake() { var order = 2; var size = 10 + rand(90); var t = (document.body.offsetWidth - 964) / 2; var x = (rand(2) == 0) ? rand(t) : t + 964 + rand(t);
    // Make it fit with my blog var y = window.pageYOffset; flakes.push({ x: x, y: y, vx:
    0, vy: 3 + rand(3), size: size, order: order }); if (flakes.length > maxflakes)
    clearInterval(snowingTimer); } function moveSnowflakes() { sky.clearRect(0, 0, canvas.width, canvas.height); var maxy = canvas.height; for (var i = 0; i < flakes.length; i++) { var flake = flakes[i]; flake.y += flake.vy; flake.x += flake.vx; if (flake.y > maxy) flake.y = 0; if (invalidateMeasure) { var t = (canvas.width - 964) / 2; flake.x = (rand(2) == 0) ?
    rand(t) : t + 964 + rand(t); } drawFlake(flake.x,flake.y,flake.size,flake.order); // Sometimes change the sideways velocity if (rand(4) == 1) flake.vx += (rand(11) - 5) / 10; if (flake.vx > 2) flake.vx = 2; if (flake.vx < -2) flake.vx = -2; } if (invalidateMeasure) invalidateMeasure = false; } }());
    Felices fiestas!

    snowflake, snow effect, JavaScript, html5, css, canvas, animation, christmas, blog

  • WarNov Developer Evangelist

    El poderoso TF.exe command

    Es posible ejecutar muchas de las tareas de administración y configuración de Visual Studio Team Foundation Server (aún el online) a través de una consola de comandos (ergo a través de scripts y PowerShell también). De igual manera se pueden realizar tareas de control de versiones y compilado.

    En este sencillo ejemplo, muestro como usar TF para obtener la información de el último Changeset que se ha incluido en nuestro TFS Online.

    Esto me surgió como una necesidad dada una estrategia de versionamiento unificada con el control de código fuente que he diseñado a través del tiempo que he dedicado a desarrollar mis productos y servicios.

    Esta estrategia sencillamente consiste en agregarle el número del changeset al final del número de versión. Ej. v 1.2.1.227 donde el 227 es el número del changeset al que se le hizo checkin con los cambios que generaron la versión como tal.

    En general, uno pone esos números de versión en archivos como el AssemblyInfo.cs para después acceder fácilmente de manera programática a ellos.

    image

    Así que lo único que hay que saber es cuál es el último número de chageset para saber cuál es el siguiente.

    Pero puede pasar que no baste solo con sumar uno al último número que tenemos en nuestro archivo:

    En TFS existen los workspaces que son agrupaciones de proyectos con los que trabajamos. Cuando se hace un checkin de uno de esos proyectos, el número de changeset dentro del workspace se incrementa automáticamente, independientemente del proyecto que haya hecho checkin. O sea que si estamos en nuestro  proyecto A en una versión *.223, uno diría que la siguiente es *.224 pero puede pasar que hayamos hecho antes de esto checkin en otro proyecto y el changeset se haya pasado ya a 224, de manera que para identificar la versión deberíamos usar *.225.

    Entonces tuve la pregunta… existe una forma fácil de saber cuál es el último changeset del workspace sin tener que ir al portal a consultarla?

    Obvio que con todo el poder de Visual Studio, la hay. Y es la herramienta TF.

    Ella tiene entre sus numerosos comandos, el de changeset y éste entre sus parámetros, el de /latest que obviamente nos brinda información del último changeset de un workspace dado.

    Precisamente para especificar el workspace dado se usa /collection:"urldelworkspace” y de esta manera si no nos habíamos logeado antes, el sistema abre una ventana de login de Microsoft account para hacer el login y luego continuar trabajando ya con estas credenciales, hasta que especifiquemos otro workspace con diferentes credenciales.

    En general el comando para obtener el número del último changeset en nuestro workspaces del tfs sería:
    tf changeset /latest /collection: "https://mitfs.visualstudio.com/defaultcollection"

    y éste se puede ejecutar desde cualquier consola de Visual Studio o de manera más cómoda, de acuerdo a como lo muestro en este post.

    Una vez ejecutado este comando, se nos abre esta ventana:

    image

    Obsérvese cómo aparece el número del último changeset (justo lo que yo necesitaba). Adicionalmente se puede editar la info de ese changeset y ver hasta qué archivos cambiaron y demás, sin tener que acudir al portal.

    Este fue solo un ejemplo del uso de TF. Existen muchos otros comandos que seguramente nos facilitarán la vida de desarrolladores avanzados y automatización y demás…

  • WarNov Developer Evangelist

    Acceso cómodo a las tools de Visual Studio

    Visual Studio no es solo IDE. También tiene programas que se pueden ejecutar independientemente del editor. Estos comandos son de fácil acceso desde la consola de comandos de Visual Studio que se instala cuando instalamos el IDE. De hecho hay varias versiones de estas consola de comandos para los últimos Visual Studio que han salido

    image

    En ciertas instalaciones de Windows 8 o superior, los accesos directos a las consolas de comandos y otras herramientas de Visual Studio 2013 no son hallables por el menú start de Windows.

    Los links a estas herramientas se encuentran en
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts

    Desde allí ya se pueden poner estos shortcuts donde más comodidad te generen como developer. De esta manera, cuando se abren estas consolas, se encuentran comandos específicos que no se hallan por ejemplo en la consola estándar de Windows, dado que no se encuentran en el path del sistema.

    Para uno como developer y con máquinas tan poderosas como las de hoy en día considero que es mucho más cómo poner la ruta real de estas herramientas en el path del sistema:

    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE;

    image

    Así pues, ya desde cualquier consola podemos llamar los comandos:

    image

    Sin tener que especificar las consolas especiales de Visual Studio.

  • WarNov Developer Evangelist

    Comprendiendo las nuevas ediciones de SQLDB (antes SQL Azure)

    Por mucho tiempo hemos tenido en Azure dos ediciones o Service Tiers de SQLDB. La web y la business.
    La única diferencia práctica de estas dos versiones hoy en día, es que la Web escala su tamaño automáticamente hasta los 5gb. Momento en el cual se bloquea y no sigue aceptando datos. La Business puede llegar hasta 150GB siendo posible fijar límites de crecimiento a los 10, 20, 30, 40 50, y 100GB.

    image

    Como aprecian, el foco de estas ediciones era el tamaño. No el performance. De hecho para ambas se tenía un performance estándar que es difícil de medir. Más adelante veremos un estimado de éste.

    Entonces basados en el feedback obtenido por parte de los usuarios, hemos introducido unos nuevos Service Tiers que están más enfocados a poder ofrecer un performance predecible. Adicionalmente estos nuevos niveles ofrecen un mayor SLA (desde 99.9% pasamos a 99.99%), bases de datos más grandes (de hasta 500GB) por menos precio y una experiencia mejorada en la facturación donde se puede ver más detalladamente los consumos que ahora no tienen como unidad mínima el día, sino de manera más conveniente, son medidos por hora.

    Los niveles actuales sin embargo siguen manteniéndose, pero solo hasta septiembre de 2015. Tiempo suficiente para hacer la migración. De hecho, se pueden seguir creando estos tipos de bases de datos de aquí hasta la fecha de retiro.

    Aparte de los cambios mencionados hasta ahora, existe otro cambio sustancial relativo a la escalabilidad de las bases de datos. Con el modelo clásico, esto se lograba a través de Federations. Un mecanismo que si bien es ingenioso y funcional, aún carece de la abstracción necesaria para por ejemplo manejarlo transparentemente desde un ORM como el Entity Framework. Entonces decidimos evolucionar el modelo de federaciones a lo que hoy conocemos como Elastic Scale; una característica que hoy se encuentra en preview y que facilita mucho más el manejo del sharding en las aplicaciones. Así que una vez retiradas las versiones Web y Business en septiembre de 2015, también dejará de soportarse la federación tal y como se conoce hoy en día. Posteriormente estaré publicando un post que nos explica estos conceptos de escalamiento horizontal en detalle.

    LOS NUEVOS TIERS
    Basic: Enfocado a bases de datos de desarrollo y testing o de aplicaciones de uso infrecuente. En general solo soportan una operación concurrente.
    Standard: La mayoría de las aplicaciones en cloud usarán esta opción dado que soporta multiples queries concurrentes.
    Premium: Orientada a aplicaciones en las que sabemos que existirá una gran carga transaccional, de concurrencia y de exigencias de continuidad del negocio. Por ejemplo las aplicaciones de misión crítica.

    Para medir el performance de estos tres niveles, hemos diseñado una herramienta llamada Azure SQL Database Benchmark (ASDB). Básicamente se usa para ejecutar cargas de tipo OLTP contra los servidores y observar el rendimiento, que se mide en DTUs (Database Throughput Unit): Una medida aplicada sobre una mezcla del rendimiento de CPU, memoria y de lecto escritura, de tal manera que un nivel de performance de 5 DTUs tiene 5 veces más poder que un performance de 1 DTU. Hay que tener en cuenta que un servidor de SQLDB soporta hoy en día hasta 1600DTUs, que son consumibles por todas las bases de datos que hospede (máximo 150). Estos límites pueden ser ampliados, tras poner un caso de soporte, de ser necesario.
    Los detalles de cada uno de los tiers y de sus subniveles se encuentran en la siguiente tabla:

    image


    Obsérvese que la predictibilidad hace referencia a la capacidad de la DB de emplear siempre el mismo tiempo ejecutando el mismo tipo de operaciones.

    En este modelo de SQLDB, es muy fácil cambiar entre los distintos niveles sin tener que suspender la operación de la DB. Ésto siempre será una operación online.

    MONITOREO:
    Básicamente proveemos dos maneras de ejecutar monitoreo sobre las SQLDB (sin necesidad de usar herramientas de terceros, que obviamente también están disponibles):
    1. A través del portal
        Se pueden agregar métricas como porcentaje de CPU, porcentaje de lecturas y escrituras en disco. Adicionalmente podemos incluir alertas de acuerdo a éstas mediciones (email). 

    image
       
    2. A traves de las Dynamic Management Views en la DB Master del servidor en el que tenemos la SQLDB.

    En conclusión, hemos observado cómo hemos introducido nuevos niveles de performance y tamaño para nuestras bases de datos como servicio, de manera que ahora tenemos más flexibilidad y poder para implementar nuestras soluciones de cloud con requerimientos de base de datos.

  • WarNov Developer Evangelist

    Alta disponibilidad en Azure (Virtual Machines)

    Subir algo a la nube (independientemente de cuál ésta sea), no significa que de inmediato tendremos alta disponibilidad. Especialmente si hablamos de IaaS.

    La alta disponibilidad en este contexto hace referencia a la capacidad que tiene un despliegue en la nube de seguir proveyendo los servicios que supone su implementación, aún cuando existan situaciones planeadas o no que afecten al hardware, al sistema operativo, a las comunicaciones o al propio software desplegado.

    Si bien en la mayoría de casos, patchs de seguridad y actualizaciones y demás son aplicados automáticamente a las máquinas virtuales en Azure sin que se afecte su operación, en otras ocasiones un reinicio de las mismas es necesario. Otras veces fallos de red o hardware requieren que las VMs defectuosas sean restauradas en otras VMs, cosa que también genera un reinicio que si no tiene respaldo ocasionará un tiempo de discontinuidad de servicio.

    Siendo algo muy obvio y no por ello menos relevante, el tener redundancia en los servidores es la alternativa por excelencia para proveer alta disponibilidad; fácil: si un servidor falla, el otro está allí para respaldarlo, mientras se reinicia el que falló (o el que se está actualizando si es que se trata de un mantenimiento programado)

    Y Azure acoge éste hecho suministrando la infraestructura necesaria para optimizar esta redundancia de servidores en los despliegues de máquinas virtuales, a través de lo que se conoce como Availability Sets (conjuntos de disponibilidad).

    En Azure, las máquinas virtuales se agrupan en VM Cloud Services (No confundir con los Azure Cloud Services de PaaS, conformados por Web y Worker Roles). Como usuarios podemos crear VM Cloud Services para agrupar VMs en términos de visibilidad de comunicación directa entre ellas. Entonces, las VMs que pertenecen al mismo VM Cloud Service se pueden comunicar entre sí sin necesidad de establecer una VPN y también pueden ser objeto de balanceo de carga interno. Pero lo más importante para este artículo, es que pueden ser ubicadas dentro del mismo Availability Set.

    Esto nos indica que un Availability Set es un subconjunto de un VM Cloud Service. A su vez un Availability Set (AS) se divide en 5 Update Domains (UD) y en 2 Failure Domains (FD). Dentro de un Availability Set,  Azure sólo reinicia las máquinas que estén en un UD particular, al mismo tiempo. Y sólo las máquinas que estén en el mismo FD comparten fuentes de poder, red y otros dispositivos físicos.

    SharedSketch

    Supongamos que creamos el AS1 para nuestro despliegue. Y luego creamos la VM1 que tiene un servidor web. Ahora asignamos VM1 a AS1. De inmediato Azure se encarga de asignar esta VM a el UD1 y al FD1. Pero hasta aquí no tenemos alta disponibilidad. De hecho, cuando en un AS solo hay una VM, Azure claramente indica que el SLA de 99.95% no se garantiza. Es más, Azure se reserva el hecho de actualizar esa VM con operaciones que requieren reinicio sin previo aviso. OJO: Cuando solo usamos una VM dentro de un AS, Azure NO NOS AVISA cuándo van a haber mantenimientos programados. Estos mantenimientos solo se avisan, si tenemos dos o más VMs dentro de un AS, a través de correos que llegan a la cuenta administrativa con antelación.

    Entonces para hablar de Alta Disponibilidad necesitamos crear un respaldo para VM1 llamado VM2, y lo asignaremos al mismo AS1 para obtener alta disponibilidad. Cuando lo hacemos, Azure también lo asigna a UD2 y al FD2.

    Y en este punto ya tendremos alta disponibilidad automática. Por qué? Pues porque como VM1 y VM2 están en distintos UD, cuando algún UD reinicie sus máquinas, estaremos seguros que los otros cuatro UDs dentro del AS no se reiniciarán. Y de esa manera nos protegemos de los mantenimientos programados, pues siempre habrán servidores listos para atender. Y si hablamos de fallas inesperadas que generalmente ocurren por fallos de hardware, sabremos que solo fallarán en este caso las máquinas que pertenecen a un FD, mientras que las que están en el otro continúan respondiendo.

    De esta manera si asignáramos más VMs al AS1, por ejemplo la VM3 iría al UD3 y al FD1 nuevamente. La VM4 en UD4 y FD2. VM5 iría en UD5 y FD1; pero VM6 volvería a UD1 y quedaría en FD2. De manera pues que si por actualizaciones Azure puede determinar que ya es hora de reiniciar las máquinas de UD1 reiniciaría al tiempo VM1 y VM6, mientras VM2, VM3, VM4 y VM5 seguirían activas.

    Una conclusión de esta metodología que no es fácil de ver a primera vista, es que servidores de distintos tiers no deberían ubicarse en el mismo AS. Por qué?

    Imaginemos por un momento que además de las máquinas anteriores, tenemos VM7 con un servidor de bases de datos. VM7 sería ubicado en UD2. Pero cuando UD2 sea reiniciado, se reiniciará el único servidor de DB y quedaremos sin servicio por unos minutos. Esto se soluciona poniendo más servidores de DB en el AS; pero al estar mezclando tiers en el mismo AS puede ocurrir que todos los servidores de DB nos queden en el mismo UD, de manera que pondremos en riesgo nuestra operación. Sumando esto a que no representa un costo adicional y que además es más fácil de administrar, lo que recomiendo es que cada tier tenga su propio AS.

    Finalmente, si combinamos la creación de un AS por cada tier de nuestra solución, con VMs redundantes dentro de cada uno de ellos y el balanceo de carga interno de Azure (No confundir con Traffic Manager), tendremos una solución muy robusta. El balanceo de carga interno permite por ejemplo detectar que una VM no está disponible y entonces se redirige el tráfico a máquinas en otros UD distintos al que se está reiniciando en un momento dado, o en otros FD si es que el FD actual sufrió alguna falla física.

    Así, ya que hemos entendido la teoría detrás de la alta disponibilidad para VMs en Azure, en este artículo se puede ver un paso a paso de cómo crear Availability Sets y como adicionar VMs a estos.

  • WarNov Developer Evangelist

    .NET Universe

    Me complace invitarlos a la serie de sesiones gratuitas de capacitación denominadas .NET Universe, a cargo de nuestros Microsoft Student Partners en Bolivia, en las cuales se verán temáticas como:

    • Introducción a la programación
    • Desarrollo de Universal Apps
    • Azure
    • Office 365
    • SQL Server
    • Windows Server
    • Desarrollo de juegos con Unity
    • Desarrollo de apps con Kinect
    • Desarrollo de páginas web con ASP.NET y MVC5
    • Entre otras actividades que vayan a salir durante el camino.

      image

    ¿Cuando?

    Ya se comenzaron con las sesiones de introducción a la programación el pasado 6 de noviembre. Se tendrán dos sesiones por semana, cada martes y jueves de 21:00 – 22:30 (GMT-4) para un total de 10 sesiones.

    En la segunda semana de diciembre, inician los cursos de desarrollo de Universal Apps, sujeto a cambios de días, pero manteniendo el mismo horario. De manera progresiva, se irán liberando las siguientes sesiones hasta culminar en Marzo del 2015 con desarrollo de páginas web en ASP.NET y MVC5.

    ¿Dónde?

    Las clases se están realizando vía Lync, pueden unirse a las sesiones de Introducción a la programación mediante este enlace. Los enlaces a futuras sesiones serán liberadas a su tiempo y podrán encontrarlas en este post.

    Recursos

    Adicionalmente, todo el material desarrollado durante cada clase (grabación de la sesión, presentaciones, código fuente, videos prácticos, etc.) está siendo subido a una carpeta en OneDrive para que puedan descargarlo.

    Únete a las sesiones de tu predilección!

    - Introduccion a la programacion Cada martes y jueves, desde el 6/11/14 hasta el 9/12/14

    - Desarrollo de Universal Apps Cada lunes y miércoles, desde el 8/12/14 hasta el 7/1/15

    - Desarrollo de juegos con Unity Cada martes y jueves, desde el 13/1/15 hasta el 12/2/15

    - Desarrollo en Kinect 2.0 Cada miércoles, desde el 14/1/15 hasta el 11/2/15

    - Administracion de Office 365 Cada lunes y miércoles, desde el 16/2/15 hasta el 18/3/15

    - Administracion de SQL Server Cada martes y jueves, desde el 17/2/15 hasta el 19/3/15

    - Microsoft Azure, Cada lunes y miércoles, desde el 23/3/15 hasta el 22/4/15

    - Desarrollo web con ASP .Net MV5 Cada martes y jueves, desde el 24/3/15 hasta el  23/4/15

    Todas las sesiones se dan de 21:00 – 22:30 (GMT -4)

  • WarNov Developer Evangelist

    Apps Multiplataforma desde Microsoft

    Atención: El nivel de este post es 50: Introductorio. Y está dirigido a lectores que no tengan experiencia en el mundo de las apps, pero requieran incursionar en este con una clara perspectiva de la estrategia que tomarán, sobre todo si están pensando en multiplataforma. [UPDATE] Si desean profundizar, al final de este post, hay una referencia a un excelente artículo de una gran amiga.

    Me preguntó el cliente: Desde la plataforma Microsoft se puede hacer desarrollo de APPs de manera que estas puedan ser multiplataforma (Android, IOs, WP)

    Hay básicamente dos caminos. El nativo y el camino de apps basadas en HTML5

    Para ambos Microsoft ofrece herramientas para construirlas desde Visual Studio

    En el primer caso, está Xamarin, que es un producto de un tercero que se adiciona a Visual Studio. Con Xamarin, las apps se construyen con C# y se crea un solo backend. El front end se puede construir también de manera común si no es muy complejo a través de Xamarin forms, o se puede optar por crear front end específicos para cada plataforma. Así que se puede aprovechar desde un 80% hasta un 100% del código original de la aplicación. La ventaja del desarrollo nativo es el performance de la app final, así como el poder aprovechar absolutamente todas las características especiales de la plataforma. Al ser un producto de un tercero, el desarrollador debe pagar una licencia para poderlo usar. Y para poder compilar para iOS, se debe tener una MAC.

    image

    En el segundo caso, se usa Visual Studio Tools for Apache Cordova en una implementación ya propia de Microsoft. Para Visual Studio 2013 update 4 es un instalador adicional y en el preview del 2015 ya viene out of the box. Como mencioné, se usa HTML, CSS y Javascript basándonos en la especificación Open Source de Apache Cordova.

    Visual Studio Tools for Apache Cordova

    En este caso no se obtiene una aplicación nativa, sino una aplicación que corre en el dominio del control de browser de cada plataform (WebView). Así que se tiene algo así como una aplicación web que corre empaquetada dentro de una app. Esto brinda la posibilidad de escribir una sola app que corra igual en todas las plataformas, pero no aprovecha las características únicas de cada una de ellas. Si la app es muy sencilla o es una app que por ejemplo los empleados de una empresa están obligados a usar, es un buen camino a seguir, ya que se aprovecha el 100% del código base tanto en presentación como en backend. Si es una app para consumidores, hay que tener cuidado con la experiencia de usuario final que se dará, pues puede que los usuarios extrañen las características propias de su plataforma preferida.

    Para mayor información, les recomiendo este post de Sorey.

  • WarNov Developer Evangelist

    Novedades para developers desde Windows Phone 8 a 8.1

    Este artículo comenzó como un correo en el que le respondía a uno de mis clientes de Servicios financieros más grandes del país, qué diferencias habrían si decidían hacer su app sobre Windows Phone 8.1 en vez de Windows Phone 8.

    Al principio empezó como algo informal, pero luego vi que valía la pena aprovechar todo lo que estaba escribiendo para que otras personas pudieran ver a grandes rasgos cuáles son estas diferencias, aunque mejor las llamaría yo: ventajas, desde un punto de vista global y no entrando en detalles aún, solo para poder imaginar el tipo de solución al que podríamos llegar; máxime ahora que mi principal dedicación en la industria está enfocada en el diseño y arquitectura global de soluciones de software.

    image

    En primera medida, no existe ningún problema en desarrollar la app para la versión del sistema operativo Windows Phone 8 y luego querer ejecutarla en teléfonos que tengan la versión Windows Phone 8.1. La aplicación en estos casos funcionaría sin líos.

    Y otro punto importante a tener en cuenta, es que todos los teléfonos con Windows Phone 8 se pueden actualizar a Windows Phone 8.1 y en verdad la mayoría de usuarios estarán motivados a hacer esta actualización. Esto, considerando que todavía hay una gran base instalada con version 8.0.

    Las desventajas que hay al desarrollar para Windows Phone 8, es que se dejarían de usar características avanzadas solo disponibles en Windows Phone 8.1 en adelante, tal como lo listo a continuación:

    1. Convergencia con las apps Windows Store (antes apps modernas o de Windows 8 – tablets, portátiles, desktops): Existe un mayor número de apis comunes entre los dos mundos y además el modelo de aplicación y el ciclo de vida de las mismas es más parecido. De igual forma con Windows Phone 8.1 se pueden aprovechar herramientas de desarrollo modernas comunes con Windows 8.1. Todo esto enmarcado dentro de lo que conocemos como Universal Apps (una sola app que aprovecha lo mejor de las tablets o teléfonos según el caso)

    2. Geofencing: Permite saber cuándo un usuario entra o sale en una zona dada dentro del mapa. Permite escenarios en los que el usuario por ejemplo recibe una notificación cuando está cerca o llega a una sucursal del negocio que maneja nuestra app.

    3. Mapas: En Windows Phone 8.1 los mapas tienen más características. Por ejemplo el almacenamiento offline de tiles para mayor rapidez de carga, soporte a gestos más complejos y mejoras en el ruteo.

    4. Transferencias en background: Ahora es posible poner uploads y downloads en cola para que se transmitan aun cuando la aplicación ya no está ejecutándose.

    5. Multimedia: Ahora es común tanto para tablets como para Windows Phone 8.1 a través del Media foundation.

    6. Push Notifications: Ahora Windows Phone usa los mismos servicios que Windows para enviar notificaciones a los dispositivos (WNS).

    7. Action Center: Nuevo en Windows Phone 8.1 permite tener en un solo sitio las notificaciones recibidas en el aparato para comodidad del usuario.

    8. Reproducción de audio mejorada

    9. Manejo de DirectX mejorado (gráficas avanzadas)

    10. En Windows Phone 8.1 se pueden grabar imágenes o videos de la actividad de pantalla del mismo. Por ejemplo para un replay en un juego.

    11. Manejo de Cámara mejorado y equiparado al efectuado en Windows Store apps.

    12. Automatización de los elementos gráficos tanto para brindar accesibilidad a través por ejemplo de lectores de pantallas, o por ejemplo para ejecutar pruebas automatizadas.

    13. Nuevas animaciones para la interfaz

    14. Manejo automático de escalamiento de texto de acuerdo a las preferencias del usuario

    15. Wallet: A través de esta funcionalidad los usuarios pueden almacenar sus tarjetas de fidelidad (puntos), tiquetes, promociones y tarjetas de pago en una ubicación central por ejemplo para hacer pagos con el teléfono a través de tarjetas virtuales prepago o con puntos.

    16. Proximidad (NFC): Mejorada y unificada en Windows Phone 8.1 con Windows Store. Además ahora se pueden marcar tags NFC como de solo lectura o escribir en tags que no se han formateado.

    image

    17. Bluetooth: Se ha mejorado por ejemplo para que se use una tarea en background de bluetooth para disparar eventos que hagan reaccionar a la app en cuestión.

    18. Seguridad: Sigue convergiendo a la ofrecida en Windows. Por ejemplo ahora ya es posible cumplir todos los estándares para ejecutar una conexión de VPN segura.

    19. Calendarios: Se pueden crear calendarios compartidos que pueden ser modificados por otras apps o por el usuario a través del calendario incluido en el sistema.

    20. Internet Explorer 11 con todas las capacidades HTML5 mejoradas que incluye tales como WebGL.

    21. Teclado en pantalla disponible para juegos

    22. Soporte para proyectar la pantalla con o sin cable

    23. File Pickers: Completamente basados en la librería tradicional de aplicaciones de Windows Store: Windows.Storage

    24. Roaming: Capacidad en Windows Phone 8.1 de almacenar datos de la aplicación que se almacenan en la nube gratuitamente a través de los servicios ofrecidos por Microsoft para estar disponibles en otros dispositivos.

    25. Contrato de Share: El contrato aunque naturalmente presenta una interfaz distinta a la de de las apps de Windows Store, permite compartir ahora URI, archivos, texto y bitmaps.

    26. Acceso a las tarjetas SD: Mientras en Windows 8 se soportaba solo el acceso a la lectura de memorias SD, en 8.1 se soporta también la escritura de las mismas. De hecho el nuevo emulador incluye soporte para simular la tarjeta SD.

    27. Instalación de apps en las memorias SD: En Windows Phone 8.1 el usuario puede escoger instalar o mover aplicaciones a la memoria SD del dispositivo. El desarrollador sin embargo puede escoger no permitir esta acción.

    28. Emulador: Se agregó soporte para multi touch y varios tamaños físicos de pantalla. También se añadió simulación de memoria SD, de ruteo GPS, deshabilitación de sensores, envío de notificaciones y testing con diferentes velocidades de conexión a la red.

    Existen algunas otras mejoras no tan notables referentes sobretodo a la convergencia del paradigma de Universal Apps, que seguro descubrirán cómodamente al estar desarrollando; pero con este listado, sabrán muy fácilmente, qué mejoras pueden hacerle a sus apps existentes en versión 8.0 o que características nuevas pueden implementar sus nuevas creaciones sobre 8.1. Obviamente también como yo, podrán argumentarle a sus clientes, por qué es mejor hacer las apps de una vez en 8.1.

    cya!

  • WarNov Developer Evangelist

    Windows Phone Update: 8.10.14203.306 for Developers

    Hoy 14 de Nov, 2014, he recibido este update dentro del programa Developer Preview que tenemos disponible para entusiastas de Windows Phone.

    image

    Las mejoras incluidas están sobretodo enfocadas en la administración de la batería.

    Tiempo de descarga: No sé, solo me apareció y ya.

    Tiempo de instalación inicial: Menos de 5 minutos en mi Lumia 1520.

    Tiempo de migración de datos: Cerca de 5 minutos teniendo ocupadas 4 gb de datos propios.

    Estrés durante el update: Menos del 5%

    Mejoras incluidas:

    El battery saver se ha incluido como una Quick Action que podemos seleccionar desde el Notification Center:

    image

    Live Tile de la app de Battery saver con información acerca del estado de la batería en tiempo real:

    image

    • Se arregló la fijación de hora automática a través de la red celular.
    • Se incluye un scheduler para programar actualizaciones del teléfono:


    image

  • WarNov Developer Evangelist

    Cómo eliminar un proyecto de Visual Studio Online

    Pues estuve viendo en la interfaz y no encontré como. Así que me tocó a través de la línea de comandos de Visual Studio:

    tfsdeleteproject /collection:https://NOMBRE-DE-CUENTA.visualstudio.com/DefaultCollection "Nombre de Proyecto"

    Asegúrense de estar logueados en Visual Studio antes de ejecutar esta opción.

    image

  • WarNov Developer Evangelist

    Añadir IP a Azure SQL DB con PowerShell

    Azure brinda enormes ventajas; entre ellas, la posibilidad de poder configurarlo y administrarlo desde cualquier parte del mundo. Sin embargo en ambientes como el de SQLDB (antes conocido como SQL Azure) para poder entrar a administrar la DB la ip de nuestra máquina de trabajo ha de estar autorizada; así que cada vez que nos conectamos desde una IP nueva, debemos entrar al portal a autorizarla… y esto me parece una pérdida de tiempo que puede ahorrarse a través de las herramientas de automatización que Azure provee tanto para línea de comandos multiplataforma (Windows, Linux, MacOS) como para PowerShell (únicamente en Windows)

    image

    Las interfaces de comandos cross platform están basadas en JavaScript y requieren de NodeJS; las puedes descargar de aquí:

    Pero; aunque hasta aquí vamos bien, podemos ir mejor! Y es que en Windows, como lo mencioné existe PowerShell que ofrece muchas más utilidades que la simple consola de comandos. Así que también se publicaron los cmdlets (así se llaman los comandos en PowerShell) para esta plataforma y los pueden descargar de aquí. El poder de PowerShell lo lleva hasta a integrarse a Visual Studio 2013, tal como lo ilustro en este post.

    Los nombres técnicos que adquirieron cada uno de estos conjuntos de interfaces fueron azure-sdk-tools para PowerShell y  azure-sdk-tools-xplat  para las consolas cross platform. Y, siguiendo los links citados, podrán observar que además de todo, tanto el código C# para PowerShell como el código JavaScript para xplat ha sido abierto y publicado en GitHub.

    Y bien, ya que los empapé con el contexto que gira alrededor de mi solución para el problemilla aquel de agregar la IP a mi servidor de SQLDB, les comento que decidí usar PowerShell con el fin de aprovechar que ahora puedo editar código PowerShell desde el mismísimo Visual Studio 2013, aprovechando características como IntelliSense y demás que hacen la codificación más agradable. Para lograr esto, instalé PowerShell Tools for Visual Studio 2013, que es una extensión para nuestro editor preferido. (Si quieres saber cómo construir tu propia extensión, haz clic aquí).

    Luego de esto, de una manera bastante cómoda escribí las siguientes líneas de código, que con fines ilustrativos comentaré de manera extensiva:

    #
    # SQLDBAuthCurrentIP.ps1
    #===========================
    #By: @WarNov 7/12/2014 - 18:12
    #This script adds to the Specified SQL DB Server Database the IP
    #of this machine as a new firewallrule
    
    
    
    Param(
    
        #Nombre del servidor SQLDB ej. p5x8y4oi1z    
        [string]$serverName,  
        #Nombre de la regla de firewall que se insertará. A pesar de ser
    #obligatorio en el comando de Azure, en este script es opcional #si se omite, el script produce un GUID como nombre
    #y lo pasa a Azure
    [string]$ruleName, #La ruta donde el archivo *.publishsettings está localizado con
    #la información de la suscripción de Azure a la que accederemos
    [string]$publish ) #Hacemos referencia a la suscripción de Azure, sencillamente
    #importando el archivo



    Import-AzurePublishSettingsFile -PublishSettingsFile $publish #Procesamos el nombre de la regla. Si viene vacío,
    #creamos un GUID. Observen el manejo que se da a los comparadores
    if($ruleName.Length -eq 0){
    #A través de .NET instanciamos la clase guid y asignamos
    $ruleName=[guid]::NewGuid(); } #Ahora obtendremos la ip que queremos agregar. #Dado que no hay forma de obtener la ip externa usada por nuestro
    #cliente es necesario usar una herramienta online que nos informe
    #cual es nuestra ip; en este caso, usaré una que construí yo mismo
    #y que corre en Azure basada en un Generic Handler sencillo de
    #ASP.NET; con esta sencilla línea de código:
    #Request.UserHostAddress #Luego a través de .NET creamos un WebClient #y ejecutamos un downloadstring especificando la url
    $ipAddress=(New-Object Net.WebClient).
    DownloadString('http://warnov.com/@ip')
    #Finalmente ejecutamos el comando principal,
    #que agregará la IP al servidor bajo la suscripción de Azure
    New-AzureSqlDatabaseServerFirewallRule -ServerName $serverName ` -RuleName $ruleName -StartIpAddress $ipAddress `
    -EndIpAddress $ipAddress

    Ya con este script listo, lo podemos ejecutar desde el mismo VS2013 para chequear si hay posibles errores.
    Una vez depurado, lo podemos llamar desde la consola de comandos, pasando como parámetro el nombre del servidor, el nombre de la regla (opcional) y la ruta del archivo de .publishsettings de Azure que se requiere para que tengamos acceso a la suscripción desde nuestra máquina. Este archivo se descarga una sola vez con este comando: azure account download

    Un ejemplo de ejecución:

    image

    Y, como en la mayoría de casos tanto el nombre del servidor como el archivo de settings es el mismo, lo que podemos es hacer otro script que ponga estos parámetros automáticamente por nosotros, así cuando necesitemos agregar la IP solo llamamos a este segundo script sin necesidad de poner parámetros.

    Así pues, hemos visto cómo mediante PowerShell podemos automatizar tediosas tareas como la de agregar la IP a Azure como una regla de firewall cada vez que queremos administrar nuestras bases de datos SQL DB desde una máquina distinta.

    He abierto el código de este pequeño proyecto en Github, donde también podrán encontrar por ejemplo, una rutina que permite borrar todas las reglas de firewall que tengamos para un servidor SQL DB dado, a través de PowerShell:

  • WarNov Developer Evangelist

    PowerShell en Visual Studio 2013


    Nuestra velocidad de vida cada vez aumenta. Y necesitamos hacer más cosas correctamente en el menor tiempo posible. En un escenario de estos, repetir una tarea, un comando, una rutina, me parece cada vez más desgastante.

    A través de la historia de la ingeniería de sistemas, siempre ha existido la manera de programar tareas a través de lenguajes tipo script con los que creamos archivos de procesamiento por lotes; por ejemplo los .bat en Windows. Desde Unix con BASH, hasta Windows con la discreta consola de comandos o el todo poderoso PowerShell (que hasta permite llamar a ejecutarse objetos .NET para desarrollar tareas inimaginables en un entorno de scripting tradicional), están hoy disponibles para que ahorremos nuestro precioso tiempo.

    Precisamente PowerShell siendo tan poderoso, cada vez toma más vigencia hoy en la industria y hasta en la vida de los desarrolladores (ya no es cosa única de IT Pros). Y en este orden de ideas lo primero que un desarrollador pensaría es:

    “… y puedo usar PowerShell desde casa? –o sea: desde el allmighty Visual Studio 2013?…”

    Hoy día me agrada responder que sí; hoy se puede y se pueden entonces aprovechar todas las ventajas de administración de código fuente tanto con git como con TFS, el intellisense, step by step debugging, etc. etc:

    image

    Esto es una maravilla en escenarios complejos en los que tenemos que manejar mucha automatización. Sobretodo ahora con Microsoft Azure, donde casi todas las tareas de configuración las podemos ejecutar a punta de comandos que tienen su representación en PowerShell a través de los azure-sdk-tools.

    Sin embargo esta funcionalidad no viene out of the box hoy en día. Tal vez en un siguiente update o release de VS, tengamos la plantilla para proyectos tipo PowerShell preinstalada. Pero pues… para eso están las extensiones de Visual Studio; en especial, PowerShell Tools for Visual Studio 2013, que es la extensión que por ahora requeriremos para trabajar con PowerShell. (Si quieres saber cómo construir tu propia extensión, haz clic aquí).

    Una vez instalada la aplicación, tendremos el tipo de proyecto PowerShell disponible:

    image

    Y una vez creado, aparece la solución con el proyecto embebido y allí podemos agregar tantos ítems como queramos:

    image

    Cada uno de esos archivos es un script PowerShell que podremos ejecutar desde la línea de comandos o con el mismo PowerShell.

    De hecho cada script se puede ejecutar desde Visual Studio propiamente para poder hacer el debug. Por ahora, el medio de escoger cual script se ejecutará es un poco arcaico, pero efectivo. Y es dar F5 mientras se tiene el foco en el archivo de script abierto que queremos depurar.

    Pues bien, arranquemos con el padre de los programas de ejemplo. El Hello World.

    En PowerShell, se escribe en consola con el comando Write-Host y entre comillas el texto a imprimir (o acaso directamente una variable como $textoAImprimir). Así que abrimos el archivo de script y escribimos:

    #
    # Script.ps1
    #
    Write-Host "hello world"
    pero cuando le damos F5, CRASH!

    [ERROR] . : File Script.ps1 cannot be loaded because running scripts is disabled on this system…

    Esto ocurre porque el scope de ejecución de VS no tiene los permisos para la ejecución de scripts.

    Pero este sencillo fix es suficiente ejecutándolo una sola vez desde Visual Studio:

    Reiniciar Visual Studio, abrir el proyecto de PowerShell, y escribir en el editor la línea

    Set-ExecutionPolicy RemoteSigned

    seleccionar el texto y presionar CTRL+F8  (O clic derecho sobre la línea y escoger ejecutar línea actual).

    Ahora borramos la línea y al presionar F5, todo funcionará sin problemas, porque Visual Studio en adelante tendrá permisos para ejecutar scripts de PowerShell:

    image

    Digamos ahora que queremos algo un poco más avanzado y es averiguar cual es nuestra IP externa. O sea con la que los servidores identifican nuestros llamados. No hay un comando estándar que nos permita saber esto. Entonces podemos recurrir a un servicio web que lo haga, o hacer webscrapping de alguna página web que retorne esta info (como cuando escribimos en el buscador what’s my ip).

    Personalmente, he creado un servicio en uno de mis sevidores de Azure que hace esto. La dirección del mismo es http://warnov.com/@ip

    Si visitan esa dirección, aparecerá un texto con su dirección IP externa.

    Entonces necesitamos un comando que pueda hacer una conexión http y bajar contenido de tipo string. Una alternativa sería instalar curl y hacer el llamado desde PowerShell, cosa que es completamente válida. Pero para darle más matiz al asunto, me permitiré hacer un llamado a .NET para traerme el nunca bien ponderado WebClient y luego decirle que baje un string desde una URL que para ilustración, vendrá dada por un parámetro:


    param
    ( #The URL from which we can obtain our current external IP [string]$serviceURL ) $ipAddress=(New-Object Net.WebClient).DownloadString($serviceURL) Write-Host $ipAddress

    Como se aprecia, hay una sección de param (esto es estándar en PowerShell). Y luego los parámetros se pueden llamar por nombre o ubicación.

    Vemos como a través de New-Object instanciamos una clase .NET. En este caso usando toda la jerarquía, llamamos a Net.WebClient para ser instanciado. Luego, a esa instancia de inmediato le llamamos el método DownloadString y como parámetro le pasamos el parámetro del script.

    Cómo se pasa ese parámetro a Visual Studio?

    Solo basta con darle clic derecho al proyecto en la solución y escoger Properties, lo que nos abre un form para escribir de inmediato los parámetros del script tal como lo haríamos en la línea de comandos:

    image

    Luego de esto ejecutamos, y obtenemos:

    image

    Y así pues, hemos creado un script usando todo el poder de Visual Studio. Además, podemos adicionarlo a git o TFS y tener todas las otras ventajas de trabajar con este poderoso IDE.

    Luego, solo basta acceder el script con PowerShell y ejecutarlo!

    image

    Es así como hemos visto la manera en la que podemos trabajar con PowerShell desde Visual Studio, ahora que será cada vez más frecuente la necesidad de usar esta herramientas en entornos de configuración y automatización. Vimos como es posible pasar parámetros al script y como ejercicio les dejo que pongan un breakpoint y vean como la ejecución se detiene y pueden evaluar el valor de las variables, como si fuera una aplicación típica de Visual Studio.

  • WarNov Developer Evangelist

    Cómo crear extensiones para Visual Studio 2013 (vsix)

    Andaba yo por ahí dando Soporte a uno de mis SaaS que tengo sobre Azure, cuando noté que era muy molesto que dado que el internet 4G que tengo me cambia en todo momento la IP, entonces siempre tenía que meterme al portal a agregar una nueva regla de firewall para poder acceder a administrar la SQL DB desde mi máquina local.

    Entonces se me ocurrió escribir un script en powershell que hiciera esa tarea en batch, de manera de que ya me podría ahorrar mucho tiempo. Además me motivó el hecho de que ahora en VS2013 tenemos un excelente plugin que nos permite desarrollar sobre PowerShell directamente desde Visual Studio.

    Pues bien, acabé de hacer mi script, e iba a pasar a poner en la documentación la fecha en la que fue creado. Pero oh sorpresa cuando noté que no tenía ni idea de cuál era la fecha en la que estábamos. Así que miré en el teléfono y vi que no podía hacer copy paste de esa fecha.

    Y bueno, abrí notepad para presionar F5, pues esto inserta la fecha y hora actual en el editor y podría copiar y pegarla en Visual Studio. Pero sucede que reemplacé Notepad por Notepad++ y este último tampoco tiene esa funcionalidad.

    Así que para nunca tener que volver a pasar por esta inmensa agonía, decidí escribir mi propia macro para Visual Studio 2013, que insertara la fecha y hora… pero; momento, las macros ya no están en Visual Studio 2013. Así que a hacer una extensión se dijo.

    Afortunadamente hoy a diferencia de cuando yo hacía las extensiones para un lenguaje de programación que estaba creando llamado APL.NET por allá en 2005, crear extensiones para VS es muy sencillo. Y obviamente, se puede a punta de código administrado.

    Basta descargar el SDK de Visual Studio 2013 que es de apenas unos cientos de megas. Después de esto ya en el mismísimo Visual Studio 2013 tendremos unas nuevas plantillas de proyecto para extensibilidad:

    image

    Las opciones son enormes. Pero para comenzar, crearemos un Visual Studio Package. Con esto será suficiente para crear la extensión que inserta un timestamp en el editor de código de Visual Studio 2013.

    Esto nos lleva a un Wizard donde primero escogemos el lenguaje y firmamos el assembly con una llave propia o una autogenerada. La autogenerada funciona bien.

    image

    Luego agregamos la información básica de nuestra extensión:

    image

    Ahora escogemos las funcionalidades ofrecidas por nuestra extensión. Como solo quiero insertar la fecha y la hora, un comando de menú basta

    image

    Asignamos un nombre programático y uno descriptivo para nuestro comando. El nombre descriptivo es el que aparecerá en el menú Tools de Visual Studio 2013 para que al hacerle clic, la fecha y hora se inserte en nuestro editor:

    image

    El soporte a testing está incluido si lo deseamos. Por ahora no lo incluiré y sencillamente daré Finish:

    image

    Obtenemos entonces una solución nueva con esta estructura:

    image

    El archivo que seleccioné es el core de nuestro comando y allí es donde lo vamos a implementar.

    Si alguna vez escribieron macros para VS con VB, recordarán el famoso objeto DTE (Development Tool Environment). Este es el objeto que encapsula toda el modelo de objetos de automatización de Visual Studio. Así que recurriremos a él para poder intervenir en el editor de código.

    El assembly que lo incluye (EnvDTE) ya viene referenciado por el wizard. Así que solo basta incluir el Namespace.

    using EnvDTE;

    Ahora buscamos el método MenuItemCallback y borramos el código por defecto que incluye.

            private void MenuItemCallback(object sender, EventArgs e)
            {
                
            }

    El código que escribamos dentro de este método será el que se ejecute cuando el usuario le hace clic al comando. Copiaré aquí todo el código con extensos comentarios para que observen como trabajé la extensión:

    private void MenuItemCallback(object sender, EventArgs e)
    {
    //Obtenemos una referencia al objeto DTE


    DTE dte = GetService(typeof(DTE)) as DTE;
    //El objeto DTE tiene un documento activo y es aquel
    //archivo de código sobre el que estamos
    //trabajando actualmente. Este documento activo tiene
    //varios objetos sobre los que podemos actuar. Aquí como
    //modificaremos el texto, hacemos referencia al contenido
    //de texto del documento activo:
    TextDocument objTextDoc =
    dte.ActiveDocument.Object("TextDocument")
    as TextDocument;

    //Este objeto de tipo TextDocument tiene un atributo
    //llamado Selection que como su nombre lo indica, nos
    //permite acceder al texto seleccionado en el editor.
    //De esta manera nos permite cambiarlo. Si no hay texto

    //seleccionado, entonces nos retorna cadena vacía.
    //Qué pasaría si cambiamos el texto en este caso?
    //Correcto, se inserta un nuevo texto en la posición actual
    //del cursor. Entonces sencillamente procedemos:
    objTextDoc.Selection.Text = String.Concat(DateTime.Now.ToShortDateString(),
    " - ",
    DateTime.Now.ToShortTimeString()); }

    Y bien, apuesto que muchos de ustedes jamás pensaron que fuera tan fácil escribir una extensión para Visual Studio 2013.

    Ahora, para probar la extensión, en Visual Studio siempre hemos tenido una gran característica que es la instancia experimental de Visual Studio. De manera que nuestras extensiones propias no vayan a dañar nuestra instalación en producción de Visual Studio. O sea que si ejecutamos este proyecto, se abre otro Visual Studio (experimental) y la extensión se ejecuta solo sobre este último (imagínense un “emulador” de VS). El debug se hace idéntico a el que se haría con cualquier tipo de aplicación convencional:

    image

    Y el resultado de hacer clic sobre el comando:

    image

    Ahora solo basta compilar ir a la carpeta bin por nuestro archivo .vsix, que es auto instalable en los sistemas con Visual Studio 2013:
    image

    Si le damos doble clic, nuestra extensión se instalará ahora sí en nuestra versión de producción de Visual Studio y ya no tendremos problema porque no sabemos en qué fecha estamos cuando vayamos a poner un timestamp! Smile

    He abierto el código fuente de esta solución y lo puedes encontrar en mi cuenta de Github:

    Por si fuera poco, si queremos compartir la extensión, la podemos subir gratuitamente a la Galería de Visual Studio donde miles de desarrolladores tendrán acceso a ella. El proceso es muy sencillo y permite además de subir la extensión ponerle tags para que por ejemplo cuando un desarrollador busque insert timestamp, obtenga resultados: 

    image

    Es más, si desde dentro de Visual Studio el developer entra a Tools->Extensions and Updates, nuestra extensión también queda disponible:

    image

    Es una excelente forma de compartir con la comunidad!!!

  • WarNov Developer Evangelist

    Usar Visual Studio 2013 con Github

    Este párrafo solo es para dar una ligera indicación de la manera más cómoda para trabajar nuestro código a ser creado con VS2013, hospedándolo en Github, sobretodo al iniciar un nuevo desarrollo.

    En este caso solo es necesario crear el repo en Github. Luego de allí sacamos la url del mismo:

    image

    Después de esto fijamos la carpeta local sobre la que queremos trabajar la solución. Una vez fijada, en Visual Studio ejecutamos el clone ANTES de crear la solución:

    Abre el Team Explorer y selecciona conexiones:

    image

    Y ejecuta estos pasos:

    image

    1. Pegar la URL del repo
    2. Ubicar el folder local
    3. Clonar el repo

    image

    Solo después de la clonación, creamos la nueva solución. Primero escogemos el repo recientemente clonado:

    image

    Y entonces tendremos la opción de asociarle una nueva solución:

    image

    Luego de crear la solución de inmediato aparece el Solution Explorer, con todos los elementos nuevos (observa el símbolo + ) listos para hacer commit y posteriormente push a Github:

    image

     

    De esta manera, ya tendríamos sincronizada nuestra nueva solución con Github, lista para trabajar.

  • WarNov Developer Evangelist

    DynamicTableEntity: Azure Storage con Entidades Dinámicas

    Recuerdo por allá en la prehistoria de Azure cuando pocos éramos los que nos aventurábamos en esas aguas inexploradas, que cuando uno quería usar el Azure Storage y en especial las tablas, tenía que generar toda una capa de acceso a datos con la parafernalia que ello conlleva para poder usar el api que en esa época se llamaba Microsoft.WindowsAzure.StorageClient.dll. Hasta la versión 1.7 se llegó con este acercamiento. A uno le tocaba SIEMPRE crear clases correlativas a las tablas que estaban en el storage y además acoplarlas a la librería lo que hacía difícil las pruebas unitarias. Adicionalmente había que crear los wrappers para hacer operaciones CRUD.

    Luego vino el revolcón de la versión 2.0 del storage API que se identifica con el cambio de nombre a Microsoft.WindowsAzure.Storage.dll y después de esto, el fuerte encaminamiento que tomamos en Microsoft para ir a toda velocidad alcanzando los estándares y tendencias de la industria, obviamente con un trabajo impecable. Es así como hoy en día con el dominio del dinamismo y temas como nodejs y demás, ya vamos en la version 4 del api. Mantenemos el nombre desde la versión 2 porque los cambios no han sido tan “breaking”. Pero sí han traído cosas maravillosas como las DynamicTableEntity.

    Gracias a ellas, podemos trabajar con las Azure Tables desde el api para .net sin necesidad de mapearlas al estilo ORM como antaño era requerido. Solo basta entender un poco las abstracciones que hemos hecho sobre el storage, para hacer los llamados correctos.

    Es mi intención entonces en este post, mostrar la manera AGIL y DINAMICA de acceder al storage, en este caso, desde una sencilla aplicación de escritorio.

    Lo primero que hay que hacer es importar el api. Agrega una referencia a Microsoft.WindowsAzure.Storage.dll. Ojo; no uses Microsoft.WindowsAzure.StorageClient.dll porque es la versión antigua que no contiene la magia que voy a mostrar ahora.

    Del api, vamos a necesitar puntualmente dos Namespaces:

    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Table;

    Acto seguido, creamos la conexión. Lo haremos “manualmente” sin necesidad de agregar más pasos por ejemplo a través del uso del CloudConfigurationManager, para mantenerlo todo más simple. Si vamos a usar el DevelopmentStorage, en este post muestro cómo hacer lo mismo.

    CloudStorageAccount _account = CloudStorageAccount.Parse(
       String.Format("DefaultEndpointsProtocol=https;AccountName={0};"
    "AccountKey={0}",
    "tucuenta",
    "45JHDAMEegL7G7wlCZhZ60UYNltbj6bZiH9x3eLHNSD1TEIQ+jw=="));

    Luego de esto, procedemos a crear un cliente de tablas. Este cliente, nos permitirá hacer todas las operaciones que requiramos con ella. Así hay clientes para blobs y colas. Anteriormente, todo esto quedaba dentro del mismo Namespace. Hoy en día, como vemos, tenemos un Namespace separado para cada elemento del storage de Azure. Aquí hemos incluido obviamente el Namespace de tablas.

    CloudTableClient _tableClient = _account.CreateCloudTableClient();

    Ahora supondremos que estamos trabajando sobre una cuenta de storage que ya tiene data probablemente obtenida a través de otra app y que lo que haremos es consultar dicha data. Usando Cloud Storage Studio:

    image

    Así pues, debemos obtener una referencia a esa tabla para poder trabajar con ella. Dicha referencia se obtiene a través del cliente que creamos:

    CloudTable _tblInventory = _tableClient.GetTableReference("Inventory");

    Ahora; cómo consultar dicha tabla sin tener una clase/entidad que la represente dentro de nuestro proyecto?

    Hay varios tipos de consultas sobre el storage de Azure. Podemos por ejemplo traer todos los elementos dentro de una partición dada, solo un subconjunto de elementos dentro de una partición, o solo un elemento obviamente especificando la PartitionKey y la RowKey. En este artículo encuentran una descripción de todas las operaciones que se pueden ejecutar sobre el storage. Solo que allí no se muestra cómo se puede operar sin necesidad de crear las entidades de mapeo. Y ese precisamente es el objeto de este post. Así que todas las operaciones indicadas allí, se pueden hacer dinámicamente, si siguen la metodología que describo aquí.

    Entonces para nuestra ilustración requeriremos hacer una consulta de todos los laptops que vende nuestra ficticia tienda de tecnología en la que en la tabla inventario tenemos como PartitionKey la categoría del elemento de tecnología, por ejemplo: compute, mobile, videogames, etc. En el RowKey tendríamos entonces la referencia de cada producto y además tendríamos entre muchas otras propiedades, la SubCategory del producto; por ejemplo, en la categoría cómputo, tendríamos subcategorías como laptop, PC, server, etc. Estamos interesados en laptops.

    Así que lo que queremos es seleccionar todos los elementos cuya PartitionKey=”Compute” y cuya Subcategory=”laptop”.

    Iniciemos entonces armando los filtros usando el método estático GenerateFilterCondition de TableQuery que trabaja así:

    (valorIzquierdo, operadorComparativo, valorDerecho):

    string categoryFilter = TableQuery.GenerateFilterCondition(
        "PartitionKey",
        QueryComparisons.Equal,
        "Compute");
    
    string subcategoryFilter = TableQuery.GenerateFilterCondition(
        "SubCategory",
        QueryComparisons.Equal,
        "Laptop");

    Ahora debemos combinar estos filtros con un “AND”, de acuerdo a nuestros requerimientos. Para esto usamos el método estático CombineFilters de la clase TableQuery que recibe dos filtros y un operador lógico.

    (Filtro1, Operador, Filtro2):

     string combinedFilters = TableQuery.CombineFilters(
         categoryFilter,
         TableOperators.And,
         subcategoryFilter);

    Como se puede ver, todo esto es mero texto. Pero usando estos metoditos nos ahorramos posibles errores al manipular mucho texto, como cuando escribíamos comandos de “T-SQL” para ejecutar por allá en los tiempos del ADO.NET. De hecho, el filtro resultante es:

    (PartitionKey eq 'Compute') and (SubCategory eq 'Laptop')

    Que si ponemos en una herramienta como Cloud Storage Studio nos da:

    image

    Todo esto porque nos basamos en el estándar de WCF Data Services Filters.


    Ahora usamos todo eso para armar una instancia de TableQuery que luego una tabla (tblInventory) ejecutará, obteniendo un conjunto IEnumerable de precisamente DynamicTableEntity, donde cada elemento es un registro coincidente con la consulta:

    TableQuery query = new TableQuery().Where(combinedFilters);
    IEnumerable<DynamicTableEntity> virtualResults = 
        _tblInventory.ExecuteQuery(query);

    Hasta aquí solo tenemos la definición del conjunto de datos que queremos y esto es Lazy; o sea que aún no se ha ejecutado contra el servidor, pues esto solo sucede cuando en realidad iteremos sobre los elementos. Por ejemplo si convertimos esto a una lista de DynamicTableEntity:

    List<DynamicTableEntity> laptops = virtualResults.ToList();

    Ahora supongamos que queremos mostrar en la consola las referencias de cada uno de los elementos filtrados (laptops) y la existencia actual. Entonces sencillamente podríamos escribir:

    foreach(var laptop in laptops)
    {
        Console.WriteLine(
            String.Concat(
                laptop.RowKey,
                "\t",
                laptop["StockAmount"].Int32Value));
    }

    Obsérvese que las propiedades nativas de las tablas de Azure como PartitionKey, RowKey, ETag, y Timestamp vienen fuertemente tipadas en una DynamicTableEntity, mientras que a las demás debemos acceder a manera de diccionario, además teniendo la facilidad de elegir el tipo de dato que vamos a recibir.

    Al final obtenemos:

    image

    De esta manera tendríamos cubierta la consulta de elementos tablas de Azure de manera dinámica.

    Ahora; cómo se haría una inserción o un update?

    Para explicar ambas cosas usaré la operación InsertOrReplace que ejecutará nuestra tabla. En este caso, primero necesitaré ejecutar la operación Retrieve para ver si el elemento que busco ya existe y modificarlo, o si no, crear uno nuevo.

    TableOperation retrieve = TableOperation.Retrieve("Compute", "X220");
    TableResult retrievedLaptop = _tblInventory.Execute(retrieve);
    //Tenemos que hacer un casting a DynamicEntity para trabajar ágilmente
    //El resultado originalmente viene en un object
    DynamicTableEntity dynaLaptop = 
    (
    DynamicTableEntity)retrievedLaptop.Result;

    Por ejemplo, llegó un embarque de 100 laptops de referencia X220 y hemos de agregarlos al inventario. Ya existirán? En ese caso debemos hacer un update. Si no, será una inserción nueva.

    Veamos; si la entidad no existe, entonces creamos una nueva:

    if(dynaLaptop==null)
    {
        dynaLaptop = new DynamicTableEntity()
        {
            PartitionKey = "Compute",
            RowKey = "Laptop"
        };
    }

    Solo las propiedades nativas de las tablas de Azure como PartitionKey, RowKey, ETag, y Timestamp vienen por defecto en una DynamicTableEntity. Las otras como “stockAmount” debemos incluirlas de la siguiente manera:

    dynaLaptop.Properties.Add("StockAmount", 
    EntityProperty.GeneratePropertyForInt(100)); dynaLaptop.Properties.Add("SubCategory",
    EntityProperty.GeneratePropertyForString("Laptop")); /*No es necesario crear propiedades para todos los campos
    existentes en la tabla. Aquí intencionalmente dejé por fuera
    ModelName y UnitPrice. Además dada la flexibilidad del
    Azure Storage, podemos agregar propiedades que no estaban
    antes en la tabla:*/
    dynaLaptop.Properties.Add("HDD",
    EntityProperty.GeneratePropertyForString("300GB"));

    Si por el contrario, la entidad ya existía, lo que hacemos es actualizarla:

    dynaLaptop["StockAmount"].Int32Value += 100;                
    //Aquí también podemos aregar nuevas propiedades
    dynaLaptop.Properties.Add("RAM", 
    EntityProperty.GeneratePropertyForString("32GB"));

    Así que ahora que ya tenemos la entidad lista para enviarla al storage usamos:

    TableOperation updateOperation = 
    TableOperation.InsertOrReplace(dynaLaptop); _tblInventory.Execute(updateOperation);

    Si luego de esto chequeamos la tabla en la nube tenemos:

    image

    Donde se aprecia que se insertó el nuevo elemento con la nueva propiedad HDD. Y que no pasó nada, por no haber indicado por ejemplo un ModelName.

    Ahora, si volvemos a ejecutar, lo que tendremos es un update, donde se sumarán otras 100 unidades y se agregará la propiedad RAM:

    image

    Y eso sería todo. La solución completa la pueden encontrar en GitHub:

    Hemos visto entonces cómo podemos acceder al Azure storage de una manera ágil y dinámica, sin necesidad de hacer montones de preparativos código circenses para lograrlo. Al mejor estilo nodejs ;) Algo muy útil cuando ya tenemos datos en la nube y queremos hacer un sencillo cliente para usarlos, sin necesidad de montar toda una arquitectura de mapeo detrás; cosa que obviamente aún sigue estando disponible para los desarrollos que lo justifiquen.

  • WarNov Developer Evangelist

    MÁS ALLA DE LOS MOBILE SERVICES: Una nueva era en el backend

    Update:

    Descarga la presentación PPT de este post de aquí:

    Y el código de ejemplo de aquí

    Seguramente ya has trabajado algo con Azure Mobile Services (en este artículo ZuMo) o al menos los has oído nombrar y sabes que son usados para que tus apps puedan acceder fácilmente a un backend a través de llamados http o de apis nativas en las plataformas de desarrollo de esas apps que lo encapsulan.

    Eso a simple vista suena muy sencillo y directo, pero en realidad nos estamos enfrentando a todo un nuevo paradigma de desarrollo que cambia las reglas y las formas en que se hacen las cosas, sobre todo para nosotros los desarrolladores que venimos del mundo .net tradicional.

    Con ZuMo podemos tratar escenarios tan abstraídos y sencillos como insertar datos en una tabla de SQL Database, reaccionar ante un update o enviar una push Notification:

    image

    Pero no estamos restringidos solo a estas operaciones básicas. Hoy en día a través de ZuMo podemos generar APIs personalizadas que podemos llamar cuando queramos. Podemos establecer Jobs que se ejecuten automática y periódicamente; podemos aprovechar los mecanismos de autenticación provistos out of the box y mantener el código y desplegarlo con GIT, entre muchas otras características provistas por esta plataforma que aprovecha lo mejor de Azure.

    En síntesis, hemos pasado de proveer un mecanismo que nos permitía guardar datos en la nube con cierta lógica, a tener todo un servidor de Backend para aplicaciones conectadas. Y obsérvese que no usé el término APPs, sino aplicaciones. Quiero decir entonces que esto no solo es para los móviles. Es tan robusto el esquema ofrecido por ZuMo, que claramente puede apoyar aplicaciones web, escritorio, etc. para ejecutar tareas específicas.

    De hecho, en ocasiones como lo veremos en este artículo, TODO el backend puede dejarse en manos de mobile services y así proveer funcionalidad a clientes web, móviles y lo que sea que pueda establecer una conexión HTTP. Y lo mejor de todo, es que esto se logra con ventajas sobre los modelos tradicionales.

    Qué ventajas se pueden obtener de un backend?

    1. Performance en la ejecución

    2. Performance en el storage

    3. Capacidad de storage

    4. Simplicidad de desarrollo

    5. Ahorro$

    Y en Azure qué elementos proveen estas ventajas?

    1. Servidores nodejs en Mobile Services
    image

    2. Azure Storage (tables, queues, blobs; particularmente: tables con su esquema NoSQL)

    Estos dos elementos tienen un performance sin igual comparado con esquemas tradicionales como los obtenidos con servidores ASP.NET o SQL Server. Adicionalmente el costo es mucho menor,

    Esto sucede ya que nodejs o el Azure storage no están enriquecidos con todas las abstracciones, características y herramientas adicionales que traen unos servidores tan robustos como IIS o SQL Server.

    Por ende, la ejecución es más veloz y los costos mucho menores!

    Son más bien elementos muy básicos que hacen extremadamente bien lo “poco” que hacen. Y esto nos lleva entonces a ver que tampoco es que sean la receta mágica de todo backend. Son más bien elementos que resuelven muy bien cierto tipo de problemas, al contrario de los servidores tradicionales que han sido construidos tratando que puedan solucionar todo tipo de problemas. Precisamente esto es lo que los convierte en piezas de software muy grandes que consumen muchos recursos y que pueden resultar más costosas.

    Esto no implica entonces que hoy en día no sigan siendo súper relevantes los servidores tradicionales (como IIS o SQL). De hecho imagínate construir todo un ERP encima de un modelo NoSQL donde no hay manejo de integridad referencial incluido en la herramienta. Eso es reinventar la rueda. Y ni hablar por ejemplo de la administración de conexiones y seguridad en los servicios que provee automáticamente IIS: en últimas tendrías que volver a escribir estos servidores para que hagan todo esto que ya se ha resuelto.

    El asunto es que hay tareas que no requieren de toda esta parafernalia. Por ejemplo una app que ofrezca resultados deportivos alrededor del mundo. Que se pueda ejecutar desde cualquier dispositivo o internet browser.

    Si lo pensamos, el modelo de datos es relativamente sencillo. Solo hay unas pocas entidades. Así que mapearlo en un esquema NoSQL, aunque es más complicado que mapearlo en un modelo E-R, no es una cosa imposible o muy difícil de hacer.

    Como es una aplicación abierta al público en general, el manejo de seguridad es bien sencillo. Además la funcionalidad la podemos mapear en sencillos métodos que ejecutan procesos sobre los datos almacenados. Estos métodos pueden ser escritos dentro de las apis personalizadas de mobile services y entonces ser llamados desde cualquier lugar del mundo a través de HTTP. Esto sin mencionar que ZuMo ofrece mecanismos de autenticación integrada con Facebook, Twitter, Google, Active Directory y la posibilidad de generar nuestros propios mecanismos.

    Obsérvese que al ser esta una aplicación mundial abierta al público, se espera una gran cantidad de peticiones por unidad de tiempo. Pero al estar todo montado en nodejs, podremos responderlas sin mucho problema y escalar de acuerdo a las poderosas ventajas ofrecidas por Microsoft Azure. El storage podrá almacenar inmensas cantidades de información (centenares de teras) y de acuerdo a cómo se hayan creado las tablas, ofrecerá unos tiempos de consulta inalcanzables por cualquier motor relacional de bases de datos (cosa que pasa por ejemplo con twitter o Facebook).

    Es este entonces un escenario propicio para implementar usando este nuevo paradigma de desarrollo en el cual se provee la lógica gruesa de la aplicación en un servidor nodejs para que los clientes (apps o browsers) puedan acceder a ella y el código que necesiten internamente sea mínimo. Facilitando por ende la engorrosa tarea de la portabilidad y esta es otra inmensa ventaja que sale naturalmente a través de este cambio.

    Con lo anterior solo bastaría hacer ciertas salvedades antes de dar el paso e ir a programar nuestro backend con nodejs en Mobile Services y Azure table storage.

    1. Mobile Services YA soporta .net como plataforma, a través de WebAPI. Esto permite que el desarrollador pueda hacer su backend sin necesidad de aprender nodejs. Pero como la arquitectura .net es distinta a la nodejs, entonces no se tendrán las ventajas de performance obtenidas con nodejs.

    2. Mobile Services SIEMPRE ha soportado SQL Database. Así que si se requiere generar un backend contra un modelo relacional tradicional (el desarrollo es más sencillo), no hay ningún problema.

    3. Desarrollar para nodejs y Azure table storage no es tan sencillo como desarrollar .net sobre un modelo relacional. Muchas abstracciones del modelo tradicional no se encuentran en nodejs ni el table storage. Así que en general habrá que esforzarse un poco más en el desarrollo y entender muy bien los conceptos de la arquitectura de un único hilo que no se bloquea en nodejs o de la forma en que las tablas nosql trabajan.

    4. No existe un IDE completo que abarque todo el ciclo de desarrollo con nodejs y Azure Storage. Por ejemplo con Visual Studio y ninguna otra herramienta adicional, es posible construir toda una aplicación cliente servidor desde la misma base de datos, pasando por la lógica de negocio, hasta el cliente web y las apps Windows. De hecho aunque el soporte a Javascript ha mejorado enormemente aún siguen habiendo algunas falencias:

    i. La habilidad de tener un tipo de proyecto que sea solo JavaScript: Esto se puede emular con un proyecto de tipo web, pero no es tan práctico

    ii. Incluir un ejecutor de scripts que use por ejemplo el intérprete de nodejs integrado: Emulable usando la Nugget Package Manager console para ejecutar los scripts.

    iii. No existe una integración visual con GIT para mantener y desplegar el código a Azure: Emulable usando la Nugget Package Manager console para ejecutar los comandos de GIT pero no en modo visual.

    iv. No existe un debugging difuso en tiempo de diseño para minimizar errores en un lenguaje interpretado como JavaScript: Update: El update 2 de Visual Studio 2013 ya incluye JSHint integrado en la edición de JavaScript, que permite tener más confianza y velocidad en el JavaScript que escribimos a través de su analizador de código estático:

    image

    5. No existe un cliente REST integrado para hacer testing rápido de los Servicios: Se puede usar una herramienta separada como Fiddler o Postman para hacer este testing, o tal vez usar curl desde la consola de NPM.

    Dadas todas estas condiciones recomiendo altamente usar un editor Javascript avanzado mientras existe más soporte en Visual Studio para lo que podríamos llamar proyectos Javascript o nodejs como tal. Una buena alternativa sería WebStorm, aunque no es gratuito, pero tiene versiones para Windows, Linux y Mac y posee todas las características descritas anteriormente.

    Adicionalmente para operar rápida y eficientemente el Azure Storage, recomiendo ampliamente Azure Management Studio de Cerebrata. Que a pesar de no ser gratuito ofrece numerosas ventajas para tener un buen entorno de desarrollo sobre el cloud en la parte del storage. Una alternativa gratuita podría ser Azure Storage Explorer.

    La metodología descrita hasta ahora, la he sumarizado luego de desarrollar varios proyectos sobretodo enfocados a aplicaciones móviles. Y para darle identidad, he creado el término nojats. Una aplicación nojats, está hosteada en Azure,  tiene su backend en nodejs (noj) y el almaceniamiento lo maneja con el Azure Table Storage (ats).

    Así que luego de esta introducción a las aplicaciones nojats, en posteriores posts, estaré mostrando más detalles de cómo optimizar el ambiente de desarrollo para explotar al máximo todas las ventajas que les he mencionado.

    Particularmente mostraré en la siguiente entrega cómo usar WebStorm para optimizar el trabajo con JavaScript Azure Mobile Services.

  • WarNov Developer Evangelist

    El titán ágil (Los Resultados)

    image

    Este es el desenlace de la dupla de posts que emergieron como consecuencia del gran cambio que está teniendo Microsoft desde sus entrañas técnicas, logrando una velocidad de desarrollo y evolución que creo no se habían visto nunca. Esta parte tiene un toque netamente técnico mostrando los últimos anuncios del TechEd para tener en cuenta en tus futuros proyectos de software. Si quieres leer la primera parte que es más teórica, puedes hacer clic aquí.

    Los anuncios fueron tanto para developers como para IT Pros.

    Como los estaré mencionando a manera global, incluiré un resumen de ambos, para nuestra cultura general.

    Developers:

    Comencemos con Azure API Management: Las organizaciones podrán exponer los componentes públicos de su core de negocio de manera segura y escalable a través de proxies en Azure que exponen estos componentes con APIs que se consumirán por nuevos clientes. Este servicio hace transparente la administración, elasticidad y configuración de las apis expuestas, minimizando las operaciones adicionales para establecer este nuevo canal para las empresas.

    image

    En cuanto a caché, Azure Cache Services pasa a disponibilidad general mientras que a evaluación entra nuestro Azure Redis Cache basado en el OSS Redis. Este será accesible por cualquier aplicación dentro de Azure.

    image

    Y si siempre quisiste tener en Azure una máquina de desarrollo accesible desde cualquier parte del mundo, ahora es posible, ya que para todos los suscriptores de MSDN están disponibles las imágenes de máquinas Windows 7 y Windows 8.1 en el catálogo de máquinas virtuales para que despliegues en la nube.

    Recuerda sin embargo que para mantener nuestros desarrollos EN la nube, también tenemos disponible Visual Studio Online que ahora expone APIs que permitirán la integración con servicios de terceros, de manera que las organizaciones lo puedan adoptar sin abandonar las herramientas que están usando actualmente mientras los desarrolladores pueden construir apps en cualquier plataforma que pueda consumir estos servicios. Adicionalmente, hemos hecho una asociación con OpsHub con el fin de ofrecer una utilidad de migración gratuita desde TFS hasta Visual Studio Online. Y para finalizar en cuanto a mejoras para la administración de los proyectos de software, anunciamos el soporte a Desired State Configuration (DSC) a través de nuestra herramienta de Release Management para Visual Studio mediante la cual a través de scripts de PowerShell podremos administrar infraestructura de despliegue de nuestras aplicaciones no solo nivel on premises, sino cloud también, aún en un mismo proyecto de despliegue híbrido. Así que ya no hay que recurrir a servicios externos como Puppet o Chef.

    También anunciamos la liberación de BizTalk Server 2013 R2, el Update 2 de Visual Studio 2013 con cuyas novedades se podría escribir un tratado completo y ASP.NET vNext, nuestro framework web orientado de manera nativa a la nube que sale a evaluación y será parte de .NET Foundation como un proyecto OSS que correrá en múltiples plataformas a través de una asociación con Xamarin.

    Las actividades con Xamarin son varias, recuerden también que gracias a ellos los desarrolladores .NET podemos compilar apps nativas hechas con Visual Studio para iOS y Android. Pero además, ahora también anunciamos otra estrategia multiplataforma que vamos a poder usar para hacer apps desde Visual Studio y es la integración con Apache Cordova (Multi-Device Hybrid Apps for Visual Studio – CTP). Con estas herramientas, los desarrolladores web podemos usar nuestros conocimientos en HTML y Javascript para crear aplicaciones híbridas empaquetadas que toman ventaja de las capacidades de cada dispositivo.

    Ahora IT Pros. Ojo, que muchos de los anuncios para IT Pros, también aplican para Developers.

    IT PROS

    Comencemos con Microsoft Azure: ya hemos puesto en disponibilidad general las máquinas A8 y A9 con una capacidad de procesamiento gigante para hacer modelaciones, simulaciones y renderizado de películas, por ejemplo. Igualmente nuestra tecnología de ExpressRoute está disponible para crear conexiones de red físicas directas y privadas entre el data center propio de una empresa y la nube de Azure; a parte de seguridad esto nos provee unas velocidades de transferencia inigualables. De hecho otro mecanismo que ahora proveemos para transferir archivos desde y hacia la nube, es Azure Import/Export que permite agregarlos o extraerlos a través de discos duros físicos como tal; obviamente esto facilita la transferencia de grandes cantidades de información que tal vez queramos compartir entre nuestros servicios de nube provistos por distintas instancias. Y precisamente para apoyar la compartición de archivos en la nube, acabamos de implementar Azure Files. A través de esta tecnología podemos crear un repositorio de archivos compartidos a través del protocolo SMB, montado sobre nuestras máquinas virtuales en Azure. Esto permite que compartamos los archivos de una ubicación centralizada de manera concurrente entre otras varias máquinas virtuales o roles de plataforma como servicio.

    Una característica que me ha encantado y que siempre me habían solicitado mucho, es Azure RemoteApp, a través de la cual las aplicaciones de negocio que corran sobre Windows Server se pueden ejecutar desde la nube, permitiendo a los clientes conectarse a ellas desde sus PCs, laptops, tablets o teléfonos a través de Microsoft Remote Desktop para ejecutarlas como si corrieran localmente, mientras esas apps escalan y se actualizan de una manera muy sencilla.

    Otras nuevas características de nuestra nube: Balanceo de carga interno de máquinas virtuales disponible, Traffic Manager pasa a disponibilidad general permitiendo controlar la distribución del tráfico de los usuarios a distintos endpoints tanto dentro como fuera de la nube, mientras Biztalk Hybrid Connections permite que desde Azure nos podamos conectar con cualquier recurso de una red local via HTTP o TCP, sin necesidad de escribir código adicional; además para la conectividad ofrecemos VPNs de tipo site-to-site y VNET-to-VNET, reservación de IPs públicas fijas, implementación de seguridad con Microsoft Antimalware y con productos de partners nuestros como Trend Micro y Symantec, mejoras en Azure Active Directory Premium que incluyen el nuevo motor de sincronización llamado Azure AD Sync y para finalizar, esperamos en Junio Azure Site Recovery: un mecanismo que permite replicar máquinas virtuales ubicadas en el date center del usuario, directamente a Azure, o a cualquier otro data center!

    Bien, ya sabes que cosas nuevas ofrece el mundo Microsoft para ti. Así que solo basta con que emplees lo que necesitas para materializar esa solución que tienes en mente. Cualquier duda o comentario, es bienvenido! Con gusto los atenderé. Smile

  • WarNov Developer Evangelist

    El titán ágil (La transformación)

    Definitivamente esta es otra era. Sobre todo para Microsoft. Pueden ser varios los motivos y sabemos que por algún tiempo parecía que el titán reposaba sobre el palacio que construyó en las últimas dos décadas, mientras nuevos titanes se hacían y construían sus propios palacios que a decir verdad, por grandes que sean, solo llegan a ser como una habitación del primero. Y tal vez esto mismo le dificultó en su momento moverse tan rápido como sus competidores.

    clip_image002

    Uno se pone a ver y si se hiciera una matriz de empresas y sus competidores, la que más tendría intersecciones sería efectivamente Microsoft y esto no es más que el fiel reflejo de la injerencia que se tiene en la industria. Y analistas como Gartner, muestran que ya a la hora del retorno de la inversión se ven los resultados de esta grandeza:

    Así que en realidad el tamaño aquí no tiene comparación.

    Esto no quiere decir sin embargo que el titán no pueda despertar de los laureles y ponerse en forma para aprender a ser ágil! Sobretodo viendo que hay tanto en disputa. Tanto que se está perdiendo. Tanto que se puede ganar.

    A estos hechos que hoy día acaecen puedo tildarlos como afortunados dado que nos han obligado a espabilarnos y en realidad hacer evidente el material del que estamos hechos en Microsoft.

    Tanto así, que no ha terminado de pasar el Build (la conferencia más importantes para desarrolladores de Microsoft) que definitivamente me dejó abrumado con toda la cantidad de cosas anunciadas (y eso que ya en secreto conocía algunos de los anuncios), cuando ya apenas pasado un mes llega el TechEd con otra ola de novedades que amenaza con freírnos el cerebro a quienes trabajamos sobre esta brillante plataforma.

    Producir tantos updates y novedades en tan poco tiempo realmente requiere unas calidades que no se logran de la noche a la mañana. Son calidades que abundan en Microsoft, pero que no habían podido desplegar todo su potencial hasta que en esta coyuntura se han mostrado aún desde los mismos grandes líderes internos como el mismísimo Nadella o el genial Guthrie.

    Cuando me imagino a los grupos de desarrollo de producto allá en Redmond no puedo evitar preguntarme como están haciendo para ir tan increíblemente rápido… y me maravilla pensar entonces qué cosas tendremos de aquí a un año… qué estaré evangelizando y usando en los productos que genero. Es sencillamente fantástico y me encanta ver un futuro tan promisorio.

    Sin embargo tratar de digerir todo este contenido puede llegar a ser como haber pedido unas onces y a cambio recibir entrada, plato fuerte, postre y café… pero para 8 personas y consumirlo y digerirlo antes de que llegue la cena.

    En la mayoría de casos lo que recomendaría es que de acuerdo a tu especialidad te “comas” solo lo que te va a alimentar. Bien sea que vas por web, por apps, por dbs, o por backend. Para todos tenemos en nuestro menú.

    En otros casos como el mío, tenemos que estar al tanto de todas las posibles opciones que hay para poder imaginar cómo será nuestro siguiente producto de software y accionar los recursos requeridos para que hagan una implementación impecable.

    De cualquier manera, es útil encontrar en algún lado el abrebocas que nos deje saber de qué trata el plato fuerte que escojamos consumir… o tal vez queramos solo tener un almuerzo de entradas, porque solo con eso basta para satisfacer nuestra hambre conceptual. Precisamente en el desenlace de este post: El titán ágil (Los Resultados) que publicaré el día lunes, encontraremos ya este contenido meramente técnico que nos dejará al día con todas las cosas nuevas en las tecnologías de cloud y desarrollo de Microsoft desde un punto de vista global.

    Por último quiero reafirmar algo que ya muchos están notando pero sé que otro tanto aún no conoce, para que ustedes cuando puedan se lo cuenten: y es que ese titán que veían por allá aislado y muy pausado en su andar, hoy es otro que socializa más con todos los chicos de la cuadra y que además parece que ha aprendido parkour, porque ahora va a una velocidad vertiginosa librando todos los obstáculos que se atraviesan en su camino. Estoy seguro que más de ustedes querrán acompañarme a montarme en hombros de este titán que nos ayudará a convertir en realidad nuestros sueños tecnológicos de unas formas que difícilmente imaginábamos antes.

  • WarNov Developer Evangelist

    Presentando: Microsoft Project Siena

    Microsoft Project Siena (nombre código) es una nueva Tecnología en Beta que permite crear apps orientadas a línea de negocio (LOB Apps) sin ningún tipo de programación, aprovechando los datos y contenido corporativos, así como servicios web.

    Estos son algunos ejemplos de los tipos de apps que se pueden crear con Microsoft Project Siena:

    • Apps para consumir información, como catálogos de productos y planes de entrenamiento basados en vídeo.
    • Apps para toma de decisiones, tales como reclamaciones de seguros.
    • Apps para capturar datos, imágenes, audio y escritura a mano en terreno.

    Construir una aplicación de Siena es tan fácil como editar una presentación de PowerPoint o una hoja de cálculo Excel. Basta incluir algunas imágenes en la app y enlazarlas a un conjunto de datos o servicios.

    Para la lógica especial se pueden escribir algunas expresiones al estilo de las usadas en Excel. Se puede utilizar la app inmediatamente, o compartirla con colegas.

    En este video, veremos como en minutos tenemos lista una app de catálogo de ventas sin ningún esfuerzo.

  • WarNov Developer Evangelist

    Lightswitch: Evitar que el doble clic abra ventana de edición en la vista Lista/Detalle

    En Lightswitch podemos crear pantallas de lista/detalle para poder ver o editar fácilmente numerosos registros.

    Estas pantallas tienen una funcionalidad interesante y es que si damos doble clic a un elemento en la lista:

    clip_image002

    un popup editable se abre con dicho elemento listo para editar:

    clip_image004

    En ocasiones deseamos impedir este comportamiento; sobre todo cuando no es necesario tener un formulario de edición dedicado que además por defecto trae todos los campos de la tabla: situación que podemos considerar no conveniente.

    Sin embargo, es difícil encontrar una opción que diga por ejemplo: Impedir pop up al hacer doble clic sobre un ítem.

    La cuestión, es que para evitar este comportamiento lo que hay que hacer es eliminar la capacidad de edición del elemento seleccionado de la lista.

    Esto se logra en modo de edición de la pantalla, entrando al command bar de la lista y de allí quitando el comando editar:

    clip_image005

    Una vez lo quitamos, observaremos que el doble clic sobre una entrada no produce ningún efecto en la interfaz.

  • WarNov Developer Evangelist

    Devices and Services. Un relato a partir del Nokia X.

    El consumidor final en general no compra sistemas operativos. Compra aparatos. Obviamente estos aparatos para funcionar bien requieren de un buen OS. Pero en un mundo de dispositivos que tienen que ser cada vez más baratos, la existencia de un excelente conjunto de servicios se hace indispensable. Y como tú, desarrollador; debes saber, los servicios que triunfan son aquellos agnósticos de los clientes que los usarán; (obviamente porque podrán alcanzar a un mayor número de dispositivos) ergo, son agnósticos del OS sobre el que correrán.

    En últimas, todo esto reviste de protagonismo a los SERVICIOS sobre el OS, en especial cuando hablamos de dispositivos móviles que al final vienen siendo los que masivamente terminarán vendiéndose dada su naturaleza multipropósito y portabilidad. Otros aparatos como los PCs serán herramientas para profesionales o usuarios avanzados, que en realidad necesitemos de todas las prestaciones de éstas maravillosas máquinas. Pero aún en éstas, los SERVICIOS son fundamentales para ofrecer más funcionalidad a los usuarios.

    Situaciones como las descritas y otras similares han llevado a la transformación de Microsoft en una compañía precisamente dedicada a los Dispositivos y Servicios. Los OS siguen existiendo y evolucionando por supuesto, pero ya como una realidad sentada. El enfoque ahora se eleva a una abstracción mayor que se ajusta a la realidad y futuro de nuestra industria.

    Existen hechos en la industria innegables para los jugadores de este cambiante partido. Por ejemplo, a través de la historia reciente, las computadoras MAC, siempre se han distinguido por su exclusividad y poca apertura a integrarse con sus competidores. Sin embargo, no dudaron en habilitar sus máquinas para que pudieran ejecutar al OS de escritorio con mayor share en el mercado global: Windows

    clip_image002

    Esta característica sin duda alguna ha representado más compras de este tipo de aparatos.

    Por otro lado, Google por ejemplo tiene su propio ChromeOS y quiere vender muchos aparatos con este OS. Pero no por eso retiró el browser Chrome de Windows. Si lo hiciese, perdería todo el share que tiene en nuestra plataforma.

    Ahora bien… si tu fueras uno de los fabricantes de teléfonos móviles más importantes del mundo que además ha entrado en alianza con uno de los gigantes de los servicios de software a nivel mundial y observas que existe una gran población que no está cubierta con tus dispositivos actuales (hablo de los mercados emergentes) y ves que además existe una forma económica de llegarles (con teléfonos de menos de 100 euros), no aprovecharías la oportunidad para abrir una nueva raza de dispositivos para poder tener una tajada más grande del mercado?

    Con esto, además de ganar por la venta de los dispositivos como tal, también ganarás porque más usuarios estarán usando tus servicios. Usuarios que hoy no tienen que ver NADA con tu tecnología, de un modo u otro estarían entrando a tu mundo.

    Y esto no significa que lo que ya tenías hecho vaya a ser abandonado. Tu producto original es tan bueno que la adopción es excelente… de hecho, abrir la plataforma significará que tarde o temprano vas a tener usuarios provenientes de la alternativa económica que quieran tener la experiencia Premium que brinda por ejemplo Windows Phone en los aparatos Lumia. El X es un puente para llegar a los Lumia.

    Así que se van a seguir requiriendo desarrolladores y empresas que satisfagan la necesidad de tu producto premium, mientras con tus productos de entrada lo que haces es atraer nuevos clientes que empiezan a usar tus servicios de manera masiva. De hecho en mercados claves como Japón, Canadá o USA (entre otros), los X no estarán disponibles.

    Viste… servicios, dispositivos… servicios, dispositivos…

    El mismo Elop en el MWC muy escuetamente dio a conocer que todos los servicios de Google que venían out of the box con Android iban a ser reemplazados por los servicios Microsoft. Así es como por defecto vendrá OneDrive, Skype, Outlook.com y sí Bing Search!

    clip_image004

    De hecho las apps que usaban antes los servicios de Google, si quisieran estar en los teléfonos Nokia, deberán ser modificadas para reemplazar los servicios por los de Microsoft J

    Conocen la historia del caballo de Troya?

    Todo esto me parece una jugada maestra a la que no se llega sino después de pensar numerosas alternativas y de tener en cuenta muchos factores… algo como una gran jugada de ajedrez.

    El servicio de pagos con tarjetas de crédito de Google, también tendrá que ser reemplazado por los servicios de pago que ahora ofrece Nokia en conjunto con los carriers, dada la estrecha relación que tiene el otrora número uno del mundo en ventas de celulares. Esto no me trae más que pensamientos positivos ya que en los mercados emergentes la adopción de tarjetas de crédito es muy baja y una plena integración con los operadores permitirá que los desarrolladores de apps las puedan monetizar más fácilmente.

    Y hablando como app developer, podría conjeturar varios temas. Por ejemplo que la capacidad de Visual Studio para generar binarios con otras plataformas como target, tal vez ahora se enriquezca con más propósito; máxime cuando Xamarin ha dado esos gigantescos pasos al respecto… no lo sé… qué tal que esos features ya vengan out of the box en versiones express… cosas de ese estilo pueden comenzar a pasar. Como sea, son ventajas para nosotros .neteros, que escribiendo nuestro adorado C#, vamos a poder compilar para todo el mundo…

    Y desde el punto de vista de backend developer, pues aún más expectativas! No solo Microsoft sino por ejemplo el mismísimo Nokia ahora tiene la posibilidad de influenciar más con sus servicios de nube como Nokia Here. De la misma manera nosotros .neteros también tendremos la posibilidad de que nuestros backend que ya son compatibles con el resto del mundo gracias a nuestras arquitecturas (como Azure Mobile Services), ahora sean más usados y tengan mayor alcance. Como bien saben, los servicios se pagan periódicamente y entre más usuarios tengamos en el front end sin importar el tipo de aparato, más ingresos mensuales vamos a tener a través de estos servicios. Por eso es bueno tener un dispositivo amigo que implemente otros OS que tengan gran share en el mercado.

    All in all… si dejamos la pasión [guts] a un lado, y vemos con cabeza fría lo que sucede, tendremos más oportunidades para sacar provecho.

  • WarNov Developer Evangelist

    Cómo tener prioridad en los Windows Phone Updates: Developers

    También eres de los que le han dado tap ochocientas cincuenta y cuatro veces al comando “Check for Updates” de tu Windows Phone a ver si el amber ya está listo para ti?

    En ese caso, te tengo la solución:

        
    Desde Microsoft, ya hemos habilitado el plan Windows Phone Preview for Developers, que habíamos anunciado hace unos meses.

    Así que para participar, solo es necesario que cumplas una de estas tres condiciones:

    Si cumples con cualquiera de estas características, BOOM, ya te puedes bajar el Amber y el Update 3 de Windows Phone.

    Solo tienes que bajarte esta app a tu teléfono desbloqueado:

    http://warnov.com/@WPhoneUpdate3

    Luego de que la bajes, aceptas todos los términos y licencias y luego buscas updates en tu teléfono:

    wp_ss_20131015_0001wp_ss_20131015_0002wp_ss_20131015_0003wp_ss_20131015_0004wp_ss_20131015_0005

  • WarNov Developer Evangelist

    Crónica de una supervivencia anunciada

     

    El día que lo iban a botar, el WarLumia 920 se guardó en el bolsillo de la chaqueta se su dueño, con tan mala suerte, que no fue cerrada la cremallera del bolsillo y además el dueño estaría corriendo karts en una pista profesional:

    Así que al bajarse de la primera sesión de vueltas, @WarNov notó que su celular ya no estaba y de inmediato supo que en algún lugar de la agreste pista yacía su celular esperando bien a ser rescatado o acaso a ser aplastado por las pequeñas veloces ruedas de algún otro kart.

    Afortunadamente @caycedo acompañaba a @WarNov en ese fin de semana de carreras y traía embebido también su Lumia 920, plan de datos activo al igual que el desafortunado WarLumia 920.

    -Entremos a http://windowsphone.com y usemos la utilidad de localizar tu teléfono:

    clip_image002

    Dijo @caycedo

    El WarLumia 920 hacía lo posible para no quedarse perdido y emitía su ubicación permanentemente con la esperanza de ser rescatado. WarNov solo esperaba a que no lloviera mientras terminaba la tanda de carreras para poder salir a la pista en compañía de caycedo al rescate.

    No llovió.

    La pista se desocupó y los dos geeks corredores salieron en búsqueda del luchador gadget. Cada uno tomó un lado de la pista y la empezaron a recorrer minuciosamente observando cada borde, como quien busca un Smartphone en una pista de carreras: una situación bastante común y cotidiana.

    Caycedo activó la funcionalidad de hacer sonar el teléfono desde la web, a través del browser de su Lumia. Y el feedback que daba el sitio era alentador al confirmar que el timbre del teléfono había sido activado correctamente. Sin embargo, aún no se oía nada… no se veía nada.

    Pasaron un cuarto de pista, media pista, tres cuartos de pista, y nada.

    Ya desesperanzados, entraron al último cuarto de pista… cabizbajos y desanimados…

    Pero de pronto, a lo lejos un fuerte timbre comenzó a oírse… caycedo arrancó a correr hacia la fuente de aquel glorioso sonido… warnov de nuevo con el alma en el cuerpo le siguió…

    Ahí está! Ahí está!

    Y sí! Era el WarLumia 920… todo su exterior mostrando las heridas de guerra sufridas…. Pero adentro, completamente operacional:

     

    WP_000898WP_000899WP_000902WP_000903

    Estaba al final de la recta más rápida de la pista, en donde seguramente cayó a unos no despreciables 70 kilometros por hora… sobre el asfalto; expuesto justo donde pasan los autos a casi 80.

    Afortunadamente @WarNov le había comprado un case protector (poco delicado y de diseño más bien tosco), que protegió perfectamente la estructura del teléfono.

    El protector, las excelentes características del aparato y los servicios ofrecidos por el portal, todo eso siempre garantizó que el WarLumia 920 sobreviviría a una catástrofe como ésta. Y por este motivo, y muchos otros, @warnov, @caycedo y miles más han elegido Windows Phone. Realmente una alternativa súper valiosa en el mundo de Smart Phones.

  • WarNov Developer Evangelist

    C++: Ansi? Unicode? main, wmain, _tmain

    Conozco usuarios “avanzados” de C++ que programan sin entender muy bien este tema. Pero en cuando más se presenta, es cuando hasta ahora estás comenzando a aprender C++. Y lo que he visto es que en ningún lado hay una introducción adecuada a este tema, motivo por el cual me vi determinado a escribir este post.

    Encoding

    En la computación básicamente todos son números; aún los caracteres. A cada carácter le corresponde un número determinado. Esta equivalencia es lo que conocemos como encoding. Hay muchos tipos de encoding. Estos encoding al principio no tenían en cuenta lenguajes donde habían muchos más caracteres que por ejemplo aquellos del inglés. Tampoco tenían en cuenta la necesidad de representar caracteres técnicos como la @ o muñequitos como los emojis. Además, diversos encodings, tenían diversas asignaciones de números para un mismo carácter. Así que la comunicación era complicada entre sistemas con distinto encoding.

    En los encoding que tendieron a ser estándar podemos contar al encoding ANSI. Es por esto, que C y C++ pueden trabajar con éste para representar caracteres. Pero en ANSI, se usa solo un byte para estas representaciones. O sea 8 bits. Con lo que se pueden representar solo 2^8 caracteres distintos = 256. Un conjunto muy limitado para un mundo tan diverso.

    Entonces el W3C propuso un encoding con más alcance, usando 2 bytes, logrando con esto cumplir su premisa de proveer un único número para cada carácter, sin importar la plataforma, el programa, o el idioma. Este encoding es llamado Unicode y hoy en día es adoptado por líderes de la industria como Microsoft, HP, IBM, Oracle, SAP, Sun, Apple y muchos otros. Además es requerido por estándares modernos como XML, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML, etc.

    Uno diría entonces que el Unicode es lo único que se debería estar usando, pero hay que seguir dando compatibilidad hacia atrás sobre sistemas que no son compatibles con Unicode.

    Es así como C++ en Windows ofrece la posibilidad de crear programas orientados a caracteres Ansi, Unicode o Multibyte. En el encoding multibyte, algunos caracteres son de un byte y otros de varios bytes. Este acercamiento es muy usado en los lenguajes orientales como el japonés y el chino. En este artículo solo trataremos Unicode y Ansi.

    Funciones

    Entonces para diferenciar las funciones orientadas a uno o a otro, se han de usar nombres distintos.

    En especial para la función principal de C++ que es el main, se tiene el nombre wmain, cuando queremos específicamente tratar con Unicode. Si solo usaremos Ansi, entonces con main bastará.

    Pero puede ocurrir que estemos desarrollando un programa que vaya a tener varios destinos: Unicode o Ansi.

    En ese caso tendríamos que escribir dos versiones distintas del mismo no? A menos de que tengamos una manera de tener nombres comodín que se adapten a las condiciones requeridas.

    Para el main, este comodín es _tmain. Ya con esto, no tenemos que estar modificando todo nuestro código, sino solamente especificar el tipo de encoding en las propiedades del proyecto:

    image

    En Not Set, se usará Ansi por defecto.

    main, no es la única función que debe trabajar distinto cuando maneja Ansi o Unicode. De hecho todas las funciones que manejar char, tienen sus diferentes versiones. Y hay muchos comodines para esas funciones al igual que _tmain.

    Por ejemplo funciones como sprintf() o fopen() en Ansi tienen versiones swprintf() o _wfopen() para Unicode y las versiones comodín _stprintf y _tfopen

    En general se puede consultar la documentación para hallar los nombres adecuados dependiendo del resultado deseado.

    Tipos de Datos

    Los tipos de datos también tienen nombre especial. Por ejemplo el char para Ansi es char, pero para Unicode (2 bytes) es wchar_t. Mientras el comodín es TCHAR.

    Esto es importante, porque si llamamos una función Ansi, debemos pasarle tipos de datos de un byte; así mismo con Unicode. De lo contrario, en ocasiones se pueden obtener resultados inesperados sin que necesariamente se produzcan excepciones, o al menos errores o advertencias en tiempo de compilación.

    Literales

    Otro punto MUY importante, es el manejo de literales de acuerdo al encoding.

    Por ejemplo, si pasas a una función el valor “miparametro” como parámetro, esto es interpretado como que estás pasando un char *. O sea un arreglo de caracteres de un solo byte: Ansi. El problema es si lo pasas a la versión Unicode de una función, en cuyo caso vas a tener resultados no deseados. Por ejemplo, no es correcto llamar:

    wcscmp(palabraBase,"mipalabra");

    Dado que wcscmp espera 2 argumentos de tipo wchar_t. Suponiendo que la variable palabraBase es de tipo correcto, lo que sí se puede asegurar es que “mipalabra”es incorrecto porque llega como char *. Para especificar que el trato sea con Unicode, usamos el prefijo “L”:

    wcscmp(palabraBase, L"mipalabra");

    Obviamente las funciones comodín también tienen su prefijo comodín: “_T”, aunque éste último actúa más como un operador: _T(”mipalabra”) será interpretada como Ansi o Unicode dependiendo del tipo de encoding que se haya especificado.

    Finalmente para ilustrar lo anterior, les dejo las tres versiones de un sencillo programa que compara un parámetro pasado a la consola, con un literal definido dentro del código:

    Versión Ansi:

    #include <iostream>
    #include <string.h>
    
    
    using namespace std;
    
    int main(int argc, char*argv [])
    {
        if (_stricmp(argv[1], "palabraBase")==0)
            cout << "Palabras Iguales" << endl;
    }

     

    Versión Genérica:

    #include <iostream>
    #include <string.h>
    #include <tchar.h>
    
    using namespace std;
    
    int _tmain(int argc, TCHAR * argv [])
    {
        //Válido si el proyecto se ajusta a Ansi 
        //Not Set en el Character Set del Proyecto    
        if (_tcsicmp(argv[1], "palabraBase") == 0)
            cout << "Palabras Iguales (T - Ansi): " << endl;
    
        //Válido SIEMPRE
        //Pero para un funcionamiento más genérico,
        //algo como esto sería más adecuado:
        if (_tcsicmp(argv[1], _T("palabraBase")) == 0)
            cout << "Palabras Iguales (T): " << endl;
    
        //Válido si el proyecto se ajusta a Unicode
        //Unicode en el Character Set del Proyecto
        if (_tcsicmp(argv[1], L"palabraBase") == 0)
            cout << "Palabras Iguales (T - Unicode): " << endl;
    }
    Nótese la inclusión de <tchar.h> para poder tener acceso a las macros genéricas requeridas.

    Adicionalmente los bloques de ejemplo 1 y 3 son mutuamente excluyentes y dependiendo del charset definido solo una es correcta.

    Versión Unicode:

    #include <iostream>
    #include <string.h>
    
    
    using namespace std;
    
    int wmain(int argc, wchar_t*argv [])
    {
        if (_wcsicmp(argv[1], L"palabraBase") == 0)
            cout << "Palabras Iguales (w)" << endl;
    }
  • WarNov Developer Evangelist

    WinRT: Live Tiles con Background Tasks

    Los live tiles como todos sabemos, nos permiten ver contenido de una app de WinRT sin necesidad de abrir dicha app.

    Hay varias formas de obtener contenido para los live tiles de tu app.

    Una de ellas es a través de Background Tasks.

    En este video, te mostraré cómo lograr lo anterior en menos de 20 minutos.

    image

     

    Veremos cómo tenemos que crear un proyecto aparte de tipo WinRT Component para exponer la funcionalidad de nuestra tarea en background, que en este caso no es más que usar la clase SyndicationClient para descargar el RSS en este caso de mi blog: http://warnov.com/@BlogRSS

    Este RSS traerá los últimos títulos de los posts de mi blog y los expondrá como contenido para el live tile de una app que para este ejemplo, es una app vacía.

    Un tema importante es declarar un objeto deferral para que Windows no termine nuestra tarea en segundo plano cuando ésta se encuentre ejecutando operaciones asíncronas. Muchas de las fallas que he visto en los updates de los tiles con Background Tasks, obedecen a la falta de declaración de este objeto.

    Luego, basta con referenciar el assembly de nuestra tarea dentro de la app en la que deseamos los live tiles. Ajustamos el manifest declarando que usaremos una Background Task, y especificamos las imágenes para los tiles.

    Se registra la tarea en el inicio de la app y listos para el debugging.

    El debugging de tiles es especial porque éstos corren en un assembly distinto al de la app. Por lo que es necesario usar Location Debugging. Esto lo vemos de manera más precisa en el video.

    Enjoy!



Page 1 of 14 (334 items) 12345»