PInvoke.net, llamadas a la API Win32 desde .NET

Hoy me he encontrado en una situación particular: mi programa .NET llama a un ejecutable de hace ya unos cuantos años para pasarle unos datos por línea de comandos entre los cuales había unas rutas físicas a unos archivos.

Todo parecía funcionar en las pruebas pero al poner las rutas largas con espacios el ejecutable no era capaz de manejarlas y ni siquiera se quejaba, simplemente no hacía nada. Así que he pensado: ¿será por las rutas? ¿podría pasarle las rutas en el viejo formato 8.3 del DOS?

Me he puesto a Googlear y existe una función del sistema operativo Windows para tal efecto: GetShortPathName en kernel32.dll… interesante. Pero por lo visto en las clases de .NET no hay nada para hacerlo directamente, así que he seguido googleando hasta llegar a PInvoke.net.

En esta página se aglutinan cientos o miles de llamadas a la API de Windows con su llamada en C# y en VB.NET así como en C++ y por si fuera poco en el caso de GetShortPathName incluyen una funcioncilla ToShortPathName a la que simplemente hay que pasarle la ruta larga a convertir. Realmente práctico, desde luego un enlace a tener en cuenta.

Evidentemente esta información se la puede cocinar uno mismo viendo la definición en MSDN pero es más rápido si ya te lo dan mascadito.

Link | PInvoke.net: the interop wiki!

Cambio dinámico de Google API Key

Todo el que haya usado las APIs de Google sabrá que hace falta una API Key para poder usarlas. Esto en principio no es un gran inconveniente pero es realmente molesto que haya que generar una clave por cada dominio que queramos usar, ya que a veces publicamos páginas en más de un dominio a la vez.

Si la página es dinámica, no hay mayor problema: se mira el dominio en alguna variable del servidor que seguro que está a nuestro alcance y se selecciona la API Key correspondiente para usarla en el HTML generado. Hasta aquí ningún problema, pero ¿qué ocurre cuando son páginas estáticas solamente? Pues la cosa se complica.

La primera solución que he probado era usar el DOM para crear un elemento script y meterlo directamente en el head de la página, seleccionando la clave usando document.domain, pero esto no ha resultado: en Internet Explorer no había manera de hacerlo funcionar. No se reconocen las funciones que carga el Javascript de Google internamente. Un desastre….

Pero luego buscando por ahí he descubierto el AJAX API, con lo que se pueden cargar todas las APIs de Google vía código. Y luego buscando por los foros, una función no documentada: .ApiKey, que permite seleccionar la clave a posteriori. Así que ya lo tenía todo y me he puesto manos a la obra:

var key = '';

switch(document.domain)
{
    case 'www.dominio1.com':
        key = 'ABQIAA....';
        break;
    case 'www.dominio1.biz':
        key = 'ABQIAB....';
        break;
}

google.loader.ApiKey = key;
google.loader.KeyVerified = true;   // por asegurarnos
google.loader.LoadFailure = false;  // por asegurarnos

google.load("maps", "2.X");

google.setOnLoadCallback(load);

Primero se selecciona la clave a través de un simple switch y luego se carga la API usando .load. Finalmente se llama a .setOnLoadCallback() indicando la función que se llamará cuando termine la carga de los datos.

Y básicamente eso es todo. Lo he probado en Mozilla y Explorer pero supongo que funcionará en algunos más porque usa código de Google que probablemente es mucho mejor que el mio. De todos modos, como usa una función no oficial de la API, es posible que esta técnica deje de funcionar en el futuro.