martes, 7 de julio de 2015

Empezando cosas nuevas

Buenas a todos

Hace mucho que no publico nada por aquí, tengo que deciros que últimamente estoy haciendo muchas cosas, pero poco escribir. Estoy aprendiendo más Linux de lo que sabia, me compre un servidor HP N54L con el que estoy muy contento, (consume poquito y para almacenamiento que era para lo que realmente lo quiero me va de sobra) y abarcando algunos temas personales que tenia "aparcados" y me están ocupando bastante tiempo, dinero y dolores de cabeza.

También he estado experimentado la "experiencia Windows 10" y relamente me ha gustado y me gusta mucho. Me parece más lógico y usable para un equipo de escritorio de lo que es Windows 8 (aunque este funciona realmente bien).

Pero afortunadamente, las cosas se acaban y salen hacia adelante. Estoy comenzando un nuevo proyecto, he comenzado a colaborar como redactor de noticias para una web de tecnología predicneitor.com a la que os invito a todos que leáis y opinéis. El proyecto esta empezando y la web aun tiene pocas visitas, poco a poco vamos llenándola de contenido, pero es un tema bastante laborioso.

De todas formas, el blog seguirá funcionado y seguiré publicando cositas, tanto los artículos que no tengan cabida en la web, como los que si la tengan, para que podáis seguir leyendo todas mis publicaciones en un mismo sitio (no quiero volveros locos).

Espero que tengais un buen día.
Muchas gracias por leerme.
Saludetes a todos

P.D. Podéis seguirme en @Jberron, Google+ y LinkedIn



martes, 26 de agosto de 2014

Embeber una librería dentro de un ejecutable en .NET

Buenas a to@s

Hoy voy a contaros un recurso que he utilizado alguna vez para evitarme problemas derivados de redistribuir librerías. En momentos es necesario que un programa sea manejable y a poder ser indivisible, para que no se produzcan problemas derivados de la falta de algunas librerías que este utilice. Algunos leguajes de programación como Delphi solucionaban estos problemas muy bien con su característica RunOnce, por eso los programas de Delphi pesaban 2 megas cuando el mismo código en .Net ocupa poco más de 20 Kb. Dejando a Delphi de un lado, el tener la fiabilidad de que tu programa va a funcionar siempre de manera correcta y que nunca le va a faltar una librería (y ademas estas siempre van a ser la versión correcta), es algo que nos da mucha tranquilidad a la hora de redistribuirlo. 

En .Net existe una caracteriza por la que podemos integrar cualquier fichero en nuestro software. Simplemente seleccionamos el fichero, ensamblado, documento… de nuestro proyecto que queramos, vamos a propiedades y en la propiedad “Acción de compilación” seleccionamos “Recurso Incrustado”. Una vez hecho esto ya podemos llamar al cualquier fichero que hayamos incrustado en nuestra aplicación desde dentro sin miedo a que nos dé un error. Para acceder a estos podremos encontrarlos dentro del espacio de nombres de nuestro programa por ejemplo MiPrograma1.imagen.png.

Hasta aquí todo perfecto, podemos incrustar cualquier cosa, pero si probamos a hacerlo con una librería obtendremos un error en tiempo de ejecución de que no encuentra la librería. Para solucionar este problema debemos insertar una línea en el Main de nuestra aplicación y crear un nuevo método en el fichero program de nuestra aplicación para resolver las librerías gracias a los métodos de reflexión.

Dentro de nuestro main debemos escribir una línea similar a esta.
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolverComponentes);

Nos suscribimos al método que se encarga de resolver las referencias y creamos un nuevo manejado que invoque la función que vamos a crear para resolver nuestras referencias. De esta forma lo que el programa va hacer es lo siguiente, primero intenta resolver las librerías por sí mismo y sino la encuentra ira a la función ResolverComponentes que hemos creado.

La función ResolverComponentes devolverá un parámetro tipo System.Reflection.Assembly debe tener dos parámetros de entrada, un object y un ResolveEventArgs que será del que obtendremos el nombre de la librería que debemos devolver.

Esta sería una posible definición:

static System.Reflection.Assembly ResolverComponentes(object sender, ResolveEventArgs args)

Para saber cuál es la librería que necesitamos, podemos hacerlo mediante la propiedad name del segundo parámetro, en este caso args.name. Esto es muy útil si tenemos que cargar varias librerías.

Por ultimo debemos devolver la librería cargada, eso lo hacemos mediante el método load del constructor de System.Reflection.Assembly es decir System.Reflection.Assembly.Load(). Posiblemente este método no os aparezca, dado que solo existe en el constructor.

Al revisarlo os daréis cuenta de que no existe ninguna definición en la que podamos pasarle la ruta donde está la librería. Tras darle unas vueltas lo que me pareció más sencillo fue enviar un array de bytes con la librería contenida en él. Para eso primero nos definimos un System.IO.Stream que contendrá el Stream de nuestra librería. Podemos hacerlo de la siguiente forma:

System.IO.Stream _streamDeLibreria;
_streamDeLibreria = _libreriaResolver.GetManifestResourceStream("MiPrograma.Librerias.LibreriaEmbebida.dll");

Una vez definido el Stream ya solo tenemos que leer todos los bytes y devolverla en el objeto System.IO.Stream:

byte[] _arrayDeLibreria = new byte[_streamDeLibreria.Length];
_streamDeLibreria.Read(_arrayDeLibreria, 0, _arrayDeLibreria.Length);
System.Reflection.Assembly _libreria_resuelta = System.Reflection.Assembly.Load(_arrayDeLibreria);

Por último solo quedaría devolver la biblioteca:

return _libreria_resuelta;


Como podéis ver el método no es muy complicado, si un poco enrevesado pero muy útil.

Si por ejemplo necesitáis hacer esto con varias bibliotecas podéis hacer un if, swich o un select case en el que condicionáis con el nombre, por ejemplo algo así:

if (args.Name == "MiLibreria.Libreria, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1b06a8ecf2258a87")
            
Si vais a realizar esto con muchas librerías, podéis definiros una variable System.Reflection.Assembly por cada librería, cargarlas en las diferentes variables con un método como el anterior y el al función ResolverComponentes solamente debemos hacer un return de la variable previamente cargada con la librería.


Aquí os dejo el método completo para que podáis modificarlo y probarlo:

static System.Reflection.Assembly ResolverComponentes(object sender, ResolveEventArgs args)
{

System.Reflection.Assembly _libreriaResolver = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream _streamDeLibreria;

if (args.Name == "MiLibreria.Libreria, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1b06a8ecf2258a87")
{
_streamDeLibreria = _libreriaResolver.GetManifestResourceStream("MiPrograma.Librerias.LibreriaEmbebida.dll");
}
else
{
_streamDeLibreria = __libreriaResolver.GetManifestResourceStream("MiPrograma.Librerias.LibreriaEmbebida2.dll");           
}

           
byte[] _arrayDeLibreria = new byte[_streamDeLibreria.Length];
_streamDeLibreria.Read(_arrayDeLibreria, 0, _arrayDeLibreria.Length);
System.Reflection.Assembly _libreria_resuelta = System.Reflection.Assembly.Load(_arrayDeLibreria);

return _libreria_resuelta;

}


Si alguien lo necesita y lo pide lo puedo “traducir” a VB si fuera necesario, aunque creo que se entiende bastante bien. 

De la misma manera si lo "traducís" y queréis que lo publique, no hay ningún problema, poneros en contacto conmigo y lo vemos. Si alguien realiza el mismo código, lo mejora o lo modifica y lo publica en su blog, puedo poneros un enlace desde el articulo a vuestra versión.


Espero la lectura haya sido amena e interesante y sobre todo que sirva para algo.
Muy importante, si decides comentar o republicar parte de este articulo porque te ha sido útil, por favor cita la fuente y el autor del mismo (vamos cítame) y pon un enlace al artículo de mi blog

Muchas gracias por leerme.
Saludetes a todos

P.D. Podéis seguirme en @Jberron, Google+ y LinkedIn





miércoles, 30 de julio de 2014

Opera Max conclusiones de uso

Buenas a tod@s

Hoy no voy a hablarlos de un programa, ni os voy a hacer un tutorial, únicamente voy a exponer mis conclusiones al utilizarlo. La victima …. Opera MAX.

 

¿Qué es Opera Max?

 

Opera Max para los que no lo conozcáis es una utilidad creada por Opera (si Opera el de nos navegadores no el de las canciones). Esta utilidad permite comprimir todo el tráfico que sale de nuestro teléfono a través de nuestra línea móvil ahorrándonos preciados megas para que podamos disfrutar de ellos.

El proyecto pintaba muy bien y yo me apunte como tester en cuanto pude. Tuve que esperar una larga lista de espera y finalmente obtuve el preciado programa.

 

Nada más iniciarlo hubo una cosa que no me gusto, y es que para funcionar Opera Max necesita establecer una conexión VPN con el servidor de Opera para enviar el tráfico a través de la red y ahorrarnos esos megas.

 

 

Las Razones

 

Una vez probado y reprobado por mi parte puedo decir sin miedo a equivocarme que no es tan bueno como lo pintan y sobre todo que no interesa.

 

La primera razón: el consumo de batería

Tener que establecer una conexión VPN todo el tiempo consume más batería que si no tenemos que establecer. Esta conexión consume mucha batería al menos en mi caso la vida de mi teléfono se recortó en aproximadamente un 30% (siendo bueno). Normalmente llego a casa con un 30% y con opera Max funcionado todo el día, no llego a casa con el encendido. Mi S4 quedo sin batería en torno a las 20:00 y normalmente sobre las 22:00 que es cuando llego a casa tengo un 30%.

 

La segunda razón: ahorro de megas y pedida de velocidad

Tras muchas pruebas y muchos intentos, con el uso normal que le doy a mi teléfono Opera Max consigue ahorrar un 5% de mis megas con suerte.

Además existen ciertas aplicaciones que con Opera Max funcionando, al reducir la velocidad no funcionan correctamente (Viber por ejemplo no va fina). Para mi este ahorro no me parece suficiente en comparación con la pedida de velocidad.

 

 

 

 

En conclusión

 

Opera Max es interesante y reduce el tráfico, sobre todo de la navegación web pero por ejemplo, ver un video de YouTube, o enviar un mensaje por WhatsApp va a consumir lo mismo.

Para el uso que yo le doy a mi teléfono, no obtengo el beneficio suficiente en ahorro de megas en comparación con el gasto de batería ocasionado.

 

Además y por otra parte, tenemos otra razón que a los más desconfiados puede preocupar. Todo nuestro tráfico pasa por los servidores de Opera. Antes únicamente pasaban por los de nuestro proveedor de internet móvil, pero en este caso introducimos un nuevo intermediario, que aunque asegura no hacer nada con nuestros datos… fiarse es siempre un dilema.

 

Espero la lectura haya sido amena e interesante

Muy importante, si decides comentar o republicar parte de este articulo porque te ha sido útil, por favor cita la fuente y el autor del mismo (vamos cítame) y pon un enlace al artículo de mi blog

 

Muchas gracias por leerme.

Saludetes a todos

 

P.D. Podéis seguirme en @Jberron, Google+ y LinkedIn

 

about.me/jberron