Archivo de la etiqueta: Visual Studio

Charla desarrollo Windows 8 en Valencia: Slides y código de ejemplo

El pasado 4 de abril tuve la oportunidad de volver a Valencia por tercera vez consecutiva para charlar con los alumnos de la’Escola Tècnica Superior d’Enginyeria (ETSE) sobre desarrollo de aplicaciones móviles en general, y en aplicaciones para Windows 8 y Windows 8 en particular.

Durante algo más de una hora estuvimos intentando dar respuesta a las siguientes preguntas:

  • ¿Merece la pena meterse en el mundo de desarrollo para aplicaciones móviles?
  • ¿Cuanto cuesta comenzar?
  • ¿Qué son los live tiles?
  • ¿Cómo integrarnos con el sistema operativo?
  • ¿Qué opciones de publicación tenemos?
  • Y muchas más.

Para ello, estuvimos desarrollando una pequeña aplicación con las siguientes características:

  • Cliente REST para consumir la API de datos de youtube.
  • Múltiples pantallas para poder ver detalles sobre un vídeo concreto
  • Posibilidad de cargar datos desde disco, usando el File Picker
  • Preferencias integradas en el cuadro de diálogo “Settings”.
  • Posibilidad de compartir con otras aplicaciones a través del Share contract

El código fuente de ejemplo está disponible aquí: https://app.box.com/s/d5d6iot8y6v5ankz5kfy

Finalmente, la presentación se encuentra disponible en slideshare

Happy hacking!

Transformando web.config (o app.config) para depuración

Una de las características más interesantes de los ficheros web.config, es que al publicarlos podemos aplicar una serie de transformaciones a los mismos, de tal manera que ciertos datos que estén en depuración no lleguen en modo release, y viceversa.

Sin embargo, hay casos en los que nos puede ser útil tener varios ficheros config para las diferentes configuraciones de build. En mi caso, desarrollando RealPoll, me di cuenta que esto podría ser interesante, y he creado tres configuraciones:

  • Debug_FakeDB
  • Debug_LocalDB
  • Debug_RemoteDB

Para cada una de las opciones tengo un fichero web.config diferente. El problema es que la transformación solamente se aplica al publicar, y no en el proceso de depuración, por lo tanto son poco útiles estos perfiles. Sin embargo, buscando un poco en internet encontré este artículo en CodeProject en cuyos comentarios estaba la respuesta a mi problema, modificar (a mano) el fichero csproj y agregar la siguiente directiva tras la compilación (tenemos un ejemplo comentado al final de nuestro proyecto):

<Target Name="AfterBuild">
   <TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" StackTrace="true" />
 </Target>

Una vez agregada, deberemos entonces duplicar la información de nuestro web.config (o app.config si desarrollamos una aplicación de escritorio) en un fichero llamado web.base.config (por ejemplo), ya que tras cada compilación el fichero web.config se regenerará.

Dentro de cada fichero de configuración, tenemos diferentes opciones. En el caso de debug_fakedb se agrega una clave a appsettings, que luego consulto al inicializar mi código:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <appSettings>
    <add xdt:Transform="Insert" key="FakeDB" value="true" />
  </appSettings>
</configuration>

Esta clave luego la consulto a la hora de inicializar el código:

if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["FakeDB"]) == false)
    Current.Bind<IQuestionRepository>().To<FakeQuestionRepository>();

else
    Current.Bind<IQuestionRepository>().To<DBQuestionRepository>();

Lo bueno de dejar estos valores en claves de configuración es que nos permite hacer cambios “en caliente” sin tener que recompilar la aplicación, como bien recomendaban Andy Hunt y Dave Thomas en su “Pragmatic Programmer”.

En el caso de localDB agregamos la información de Entity Framework (que ya sabrá que hacer):

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <entityFramework xdt:Transform="Insert">
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

Finalmente, para el caso de remoteDB, agregamos la información de Entity Framework, así como la cadena de conexión (que más adelante se sustituye en azure):

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings xdt:Transform="Insert">
      <add name="QuestionContext"
           connectionString="YOUR_CONNECTION_STRING_HERE"
           providerName="System.Data.SqlClient" />
  </connectionStrings>
  <entityFramework xdt:Transform="Insert">
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

Para mí supone un ahorro considerable de tiempo y esfuerzo, además de que me permite probar las diferentes configuraciones sin recompilar.

Si quieres verlo en ejecución, echa un vistazo al código de Realpoll en github del que hablaré muy, muy pronto.

Moving windows programatically with Windows API, the path to WinResize

When we test VS Anywhere in a production environment, one of the things that we tend to do is to open 2 sessions of Visual Studio on either side of the screen, so we can make quick tests of specific features.

goal

This requires opening 2 different instances of visual studio by hand, and attach each side of the screen, something tedious, boring, and, above all, automatable. So I set out to find the way of solving this small issue.

The path

If we have Windows 7 or higher we can make use of Aero Snap, using Win+Left or Win+Right, it sets a window to the left or to the right of the screen. It seemed simple, I would only need to emulate this key combination, something that it seemed easy to do:

Theorically, we can solve this by using Powershell. In fact, in the following entry of TechNet Provide Input to Applications with PowerShell explains how to send commands to an application using SendKeys, resulting in the following code:

add-type -AssemblyName microsoft.VisualBasic
add-type -AssemblyName System.Windows.Forms
Calc
start-sleep -Milliseconds 500
[Microsoft.VisualBasic.Interaction]::AppActivate("Calc")
[System.Windows.Forms.SendKeys]::SendWait("1{ADD}1=")

According to the last line, we should be able to send to the program any combination of keys, so the next step was to find the Windows key in the SendKeys reference: http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(v=vs.110) .aspx

Surprise: is not there. On the other hand, looking a bit online, I found that the Windows keystroke could be simulated by using the Ctrl + Esc.

Second surprise:  IT SIMULATES the WINDOWS key, and nothing else. When you press that combination, It jumps right to the desktop or to the start menu, it is not possible to use it to simulate a key combination involving Win + whatever, so that by this way little more we can do.

On the other hand, if what we are doing is a keyboard shortcut, surely matches some kind of command available on the Windows API that makes the action of Aero Snap, but no, there is no API, no documentation and there is no reference except the brand name, so this is another dead end.

There was still another option, which was to move the window directly using a custom program, after some search I found this piece of code, allowing you to do what I wanted using Powershell:

It was not too complex, but I chose to do a small application with C# so that it could solve the problem, using native calls to the Windows API through P/Invoke:

Importing functions and moving windows

To use the Windows API functions we have to copy their header in our function, define it as external (.NET framework will already know what to do) and define the DLL from which we import, in this case the function MoveWindow is located in user32.dll:

[DllImport ("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

We will have to repeat this process for each function that we want to import, a we will also need to add the following using:

using System.Runtime.InteropServices;

To be able to move the window, we need its hWnd, which is a unique window identifier. There are many ways to locate it, and one of them is from the list of processes, selecting those whose main window matched with what was looking for, in this case “Visual Studio”.

foreach (Process proc in Process.GetProcesses ()
{
    if (proc.MainWindowTitle.Contains ("Visual Studio"))
    {
        IntPtr handle = proc.P:System.Diagnostics.process.MainWindowHandle;
        ...
        MoveWindow(handle...);
        ...
    }
}

For moving the window, we need to set an origin and a size, and for this we could either fix them manually, or rely on the resolution of the screen, using the following functions:

Screen.PrimaryScreen.WorkingArea.Width;
Screen.PrimaryScreen.WorkingArea.Height;

These are found within the namespace System.Windows.Forms, which requires in addition a reference as System.Drawing from our project.

The really interesting thing about this, is that it allows us to move the window to the position we would like with any size, so we can take advantage of it in order to set any number of windows, being these equally distributed.

Finally we need a couple of additional calls to Windows API functions to maximize the window before moving it, and to set the focus, which are imported in a similar way:

[DllImport ("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int X);
[DllImport ("user32.dll")]
public static extern bool SetFocus(IntPtr hWnd);

Launching applications and input parameters

In addition to the functionality of moving windows, it could be interesting to launch the apps we want to move, so a bit of extra code to generate a process, to set the name of the file, and, after launching it, a small sleep while loading:

Process p = new Process();
p.StartInfo.FileName = "notepad.exe";
p.Start ();
System.Threading.Thread.Sleep (2000);

To make it simpler, the last step is to convert all the parameters used to input arguments of the program, being finally the project a console application, which gets, in this order;

  • Path of the executable
  • Title of the window to search
  • Number of processes to launch
  • Waiting for each process

In the case of a 3 windows launch for notepad.exe, this is the output showing the console application:

WinResize

On the other hand we have 3 windows, equally distributed:

Result

As the last detail, the window title is set using the following code block:

Console.Title = "WinResize";

Wrapping up

This is a small app that solves a very specific scenario can be widely improved and I’ll probably work for some more time on it, here are some ideas for future improvements:

  • Make all the script in powershell, it’s possible, and we can make P/Invoke without problems
  • Emulate the keypress (must be a code associated with the windows key, and a way to press it!) simulating the keyboard.
  • Rather than take all processes available, use the ID of those we’ve just created.

The code is available for free and licensed under open source. If you want to contribute please send your pull request :)

Enjoy!

Additional links

Moviendo ventanas con la API de Windows, la historia de WinResize

Para hacer pruebas de VS Anywhere en un entorno de producción, una de las cosas que solemos hacer es abrir 2 sesiones de Visual Studio a cada lado de la pantalla, de esta manera podemos hacer pruebas rápidas de características específicas.

goal

El problema es que esto requiere abrir 2 instancias de visual studio de manera manual, y fijarlas cada una a un lado de la pantalla, algo tedioso, aburrido, y, sobre todo, automatizable. Así que me lancé a la búsqueda de la verdad, qué me puede solucionar?

El camino recorrido

Si tenemos Windows 7 o superior podemos hacer uso de Aero Snap, que usando Win+Izquierda o Win+Derecha, fija una ventana a la izquierda o a la derecha de la pantalla. Parecía sencillo, solamente tendríamos que emular esta combinación de teclas, lo cual, en un principio era algo fácil de hacer:

En teoría, usando Powershell, podríamos hacerlo, de hecho, en la siguiente entrada de TechNet Provide Input to Applications with PowerShell se explica cómo enviar comandos a una aplicación empleando SendKeys, siendo este código el resultado:

add-type -AssemblyName microsoft.VisualBasic
add-type -AssemblyName System.Windows.Forms
Calc
start-sleep -Milliseconds 500
[Microsoft.VisualBasic.Interaction]::AppActivate("Calc")
[System.Windows.Forms.SendKeys]::SendWait("1{ADD}1=")

De acuerdo con la última línea, deberíamos poder enviar al programa cualquier combinación de teclas, así que el siguiente paso era buscar la tecla Windows en la referencia de SendKeys: http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(v=vs.110).aspx

Sorpresa: no está. Por otra parte, buscando un poco por internet, encontré que se podría simular la pulsación de la tecla Windows usando la  Ctrl + Esc.

Segunda sorpresa: SIMULA LA TECLA WINDOWS, y nada más. En el momento que se pulsa eso, se salta al escritorio, o al menú inicio, no siendo posible usarlo para simular una combinación de teclas que involucre Win + cualquier cosa, así que por este camino poco más podemos hacer.

Por otro lado, si lo que estamos haciendo es un atajo de teclado, seguramente corresponda con alguna API de windows que haga la acción de Aero Snap, pero no, no hay API, no hay documentación y no hay ninguna referencia salvo el nombre comercial. con lo cual este es otro callejón sin salida,

Aún quedaba una opción, que era mover directamente la ventana usando código, tras algo de búsqueda encontré este código, que permitía hacer lo que quería usando powershell:

No era demasiado complejo, pero opté por hacer una pequeña aplicación C# para que me resolviera el problema, usando las llamadas nativas a la API de Windows a través de P/Invoke:

Importando las funciones y moviendo la ventana

Para usar funciones de la API de Windows hemos de copiar su cabecera en nuestra función, definirla como externa (el framework ya sabrá que hacer) y definir la DLL de la que realizaremos la importación, en este caso la función MoveWindow situada en user32.dll:

[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

Deberemos repetir este proceso para cada función que queramos importar, y además, para todo esto, necesitaremos agregar el siguiente using:

using System.Runtime.InteropServices;

Para poder mover la ventana, necesitamos su hWnd, que es un identificador de ventana único. Hay muchas maneras de localizarlo, y una de ellas es a partir de la lista de procesos, seleccionando aquellos cuya ventana principal coincidiera con lo que estaba buscando, en este caso Visual Studio.

foreach (Process proc in Process.GetProcesses())
{
    if (proc.MainWindowTitle.Contains("Visual Studio"))
    {
        IntPtr handle = proc.MainWindowHandle;
        ...
        MoveWindow(handle ...);
        ...
    }
}

Para poder mover la pantalla necesitamos establecer un punto origen y un tamaño, y para ello podríamos o bien fijarlos manualmente, o basarnos en la resolución de la pantalla, usando para ello las siguientes funciones:

Screen.PrimaryScreen.WorkingArea.Width;
Screen.PrimaryScreen.WorkingArea.Height;

que se encuentran dentro del namespace System.Windows.Forms, que requiere además una referencia as System.Drawing desde nuestro proyecto.

Lo realmente interesante de esto, es que me permitía mover la ventana a la posición que quisiera con cualquier tamaño, así que lo aproveché para poder establecer cualquier número de ventanas, estando estas igualmente distribuidas.

Finalmente necesitamos un par de llamadas más a funciones de la API de Windows para maximizar la ventana antes de moverla, y para establecer el foco, que se importan de manera similar:

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int X);
[DllImport("user32.dll")]
public static extern bool SetFocus(IntPtr hWnd);

Lanzando las aplicaciones y parámetros de entrada

Además de la funcionalidad de mover ventanas, podría ser interesante lanzar las aplicaciones, así que un poco de código para generar un proceso, establecer el nombre del fichero, y, tras lanzarlo, una leve espera mientras carga:

Process p = new Process();
p.StartInfo.FileName = "notepad.exe";
p.Start();
System.Threading.Thread.Sleep(2000);

Para hacerlo más sencillo, el último paso es convertir todos los parámetros usados a parámetros de entrada, siendo finalmente el proyecto una aplicación de consola, que recibe, en este orden;

  • Ruta del ejecutable
  • Título de la ventana a buscar
  • Número de procesos a lanzar
  • Espera para cada proceso

La salida que muestra la aplicación de consola es ésta, para el caso de 3 ventanas de notepad.exe:

WinResize

Por otra parte tenemos las 3 ventanas, igualmente distribuidas.

Result

Como último detalle, el título de la ventana está fijado usando el siguiente bloque de código:

Console.Title = "WinResize";

Conclusiones

Esta es una pequeña app que en mi caso soluciona un escenario muy concreto, se puede expandir hasta límites insospechados, y posiblemente lo haga, aunque hay cosas que se me han quedado en el tintero seguro, y que dejo como idea para el futuro:

  • Hacer todo el script en powershell, es posible, y podemos hacer P/Invoke sin problemas
  • Emular la pulsación de la tecla (tiene que haber un código asociado a la tecla windows, y una manera de pulsarlo!) simulando el teclado.
  • En vez de recorrer todos los procesos, usar el identificador de los que acabo de crear.

El código está disponible de manera gratuita y bajo licencia open-source. Si quieres contribuir envía tu pull request :)

Enjoy!

Enlaces adicionales

Compilando C++ desde la consola de comandos de Visual Studio

Es posible que en alguna ocasión queramos compilar un fichero individual para comprobar el funcionamiento de una función o de un algoritmo, y abrir Visual Studio, cargar un proyecto y similar se nos antoje demasiado engorroso, una posible solución es usar la consola de comandos de visual studio, y compilar de una manera rápida. Para este artículo compilaré un fichero C++ nativo.

Para ello, si tenemos Visual Studio 2010 (Professional en mi caso), puedes  encontrar, dentro de la carpeta de Visual Studio 2010/Visual Studio Tools, una utilidad llamada Visual Studio Command Prompt (2010) que cargará el entorno de desarrollo.

Una vez ahí, usando los comandos clásicos (cd carpeta) o arrastrando la carpeta a la consola de comandos, nos situamos en el directorio donde queramos realizar la compilación y escribimos:

 \> cl /EHsc nombreDelFichero.cpp 

Donde cl es el compilador, y EH permite habilitar el manejo de excepciones. Esto debería realizar la compiilación correspondiente y generar un fichero llamado nombreDelFichero.exe

Si estás acostumbrado (por otros lenguajes u otros sistemas operativos) al uso intensivo de la consola de comandos, no has de renunciar a sus ventajas en la plataforma Windows/VS.

Más información (en inglés):

Hola mundo con Kinect SDK

Kinect, originalmente concebido como un accesorio para la XBOX, ha superado las expectativas de la consola al convertirse en un dispositivo que ha cambiado la manera de interactuar con el ordenador.

En este artículo veremos cómo ha pasado de ser un mero accesorio a una plataforma para la que desarrollar proyectos interesantes. Podremos, además ver un primer ejemplo de código que usa la plataforma.

Un poco de historia

La historia de Kinect se remonta a noviembre de 2010, cuando es presentado en junio de 2009 en el evento E3 como “Project Natal”. Posteriormente en noviembre de 2010 sale al mercado como accesorio de la XBOX360. Contaba con una conexión USB que no se había protegido, lo que hizo que la comunidad de desarrolladores le prestase mucha atención, obteniéndose el primer driver de vídeo para Linux a finales de ese mismo mes.

A partir de ese momento la comunidad empezó a trabajar en este inquietante dispositivo hasta el punto de tener drivers bastante completos en poco tiempo. Microsoft decidió reaccionar lanzando una primera beta del SDK no comercial en Junio de este año (que implica que no podemos usar Kinect para vender aplicaciones ni para publicidad, de momento). Esta beta se ha actualizado el pasado Noviembre, y está previsto para principios de 2012 una nueva actualización de caracter comercial.

Nuestro primer Hola Mundo

Para poder trabajar con el SDK necesitamos Visual Studio Express, disponible de manera gratuita en la web de Visual Studio. Una vez instalado, podemos descargar e instalar el SDK, para poder empezar a trabajar con la Kinect.

El primer paso consiste en agregar la referencia al espacio de nombres que se muestra a continuación:

using Microsoft.Research.Kinect.Nui;

Una vez esté agregada, podemos escribir nuestro primer trozo de código. El código a continuación, pese a no estar completo por parámetros de inicialización muestra varias cosas:

//Inicializar el sensor
nui = Runtime.Kinects[0];
nui.Initialize(...);

nui.VideoStream.Open(...);
PlanarImage planarImage = nui.VideoStream.GetNextFrame(1000).Image;

//Cerrar la conexión
nui.Uninitialize();

La primera es que tenemos la posibilidad de contar con varios sensores Kinect, y que en este ejemplo seleccionamos solamente el primero. Posteriormente inicializamos el sensor.

El siguiente paso consiste en abrir una conexión con el flujo de vídeo, esperar 1000 milisegundos y recibir la siguiente imagen. Esta imagen la podremos procesar en nuestro código de la manera que consideremos más oportuna.

Es importante destacar que cuando terminemos de trabajar con Kinect cerremos la conexión llamando al método Uninitialize.

Para ver ejemplos más completos y complejos, en el SDK que enlazo al final del artículo puedes encontrar varios ejemplos de código funcionales.

¿Qué más incluye el SDK?

Lo que se ha visto hasta ahora es cómo obtener una imagen, sin embargo el SDK de Kinect tiene varias características adicionales:

  • Drivers (para que el PC reconozca la Kinect): Esto puede sonar bastante obvio, pero necesitamos que el ordenador reconozca todas las capacidades del dispositivo, las cámaras y los micrófonos.
  • NUI: Se engloban en este área todos los métodos relacionados con las cámaras
    • Imagen de la cámara: Lo que hemos captado antes, una imagen de lo que está captando la cámara principal en estos momentos.
    • Datos de profundidad: Es también una imagen, pero en escala de grises que es capaz de detectar la profundidad de una figura.
    • Seguimiento de esqueleto: Es una de las características más destacadas de Kinect, ya que es capaz de detectar 20 articulaciones de 2 personas diferentes orientadas al sensor.
  • Speech: Por último y no menos importante, este área engloba todos los métodos relacionados con la escucha y comandos de voz.
    • Captura de audio con detección de ruido: El hecho de que Kinect tenga 4 micrófonos permite aislar el ruido y detectar la fuente de las órdenes concretas.
    • Comandos de voz: Además, usando la tecnología de reconocimiento de voz, se pueden crear diccionarios personalizados para que el programa reconozca nuestras órdenes.

Conclusiones

Si tienes una Kinect te animo a que la desenchufes de la consola, la conectes a tu ordenador, descargues el SDK y descubras cómo funciona. Es un accesorio interesante que puede tener mucho futuro en entornos de hogar o incluso corporativos, por no hablar de temas relacionados con robótica.

Recursos:

Console.WriteLine("Felices Fiestas a todos");