Aplicaciones portables con Mono
Hay una guía sobre portabilidad de aplicaciones, que me ha resultado bastante útil, aunque la mayoría de las cosas ya las tenía en mente de cuando programé una aplicación GUI
en Java
(y quise que fuera portable, claro :P).
Mi entorno de desarrollo es Linux
con MonoDevelop y Mono 1.9.1 (que viene a ser Mono 2.0 Beta).
En general he identificado dos clases de problema a la hora de que la aplicación sea portable, aunque el segundo es solo porque quería que el programa funcionara con el runtime de Microsoft
aparte del de Mono
.
- Problemas derivados de la interacción con el sistema que se encuentra fuera de la máquina virtual.
- Problemas derivados de cambios en la implementación de las máquinas virtuales por cada runtime.
En el primer caso el documento citado más arriba es útil, porque nos encontramos con los siguientes retos:
- ¿Dónde guardamos la configuración? De entrada he descartado el registro de
Windows
, porque en el resto de plataformas no existe :D. Así que elegí la aproximación más fácil, que es crear un directorio en elHOME
del usuario, y almacenar la configuración, caché, etc, allí.La clave nos la da
System.Environment
:Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
En
Linux
(imagino que en cualquier UNIX-like, lo que incluye aMac
), se trata de$HOME
, y enWindows
parece serMis Documentos
:D. - ¿Cómo se construyen las rutas a directorios? Este es un problema clásico. Como sabemos en los sistemas UNIX-like trabajamos con la barra a la derecha como caracter separador, mientras que
Windows
emplea la barra a la izquierda (o barra invertida).Esto se soluciona con
System.IO.Path
, que nos proporciona dos métodos estáticos muy útiles:// Nos da el caracter separador Path.DirectorySeparatorChar // Permite añadir un subdirectorio a una path existente Path.Combine (basePath, subDir)
Y hasta aquí los problemas de portabilidad del primer grupo, ya que el resto de características nos las proporciona GTK#
y el API
estándar de .NET 2.0
.
Respecto a los problemas derivados de los runtime, hay cosas evidentes, y otras... no tanto :(
- No podemos usar clases de la jeraquía Mono.*: esto está claro, al menos si queremos que funcione la aplicación con el runtime de
Microsoft
, que no implementa estas clases. - Elegir el uso de las clases propuesto por
Microsoft
: si tenemos dos runtimes que no se comportan igual, en este caso el deMono
es el más flexible porque que es el que busca ser compatible, tendremos que hacer que funcione en el restrictivo.
Entonces es cuando te das cuenta de lo complicado que es :(.
Si trabajamos con Mono
en Linux
nos encontraremos con que, siguendo la documentación (que es excelente), tenemos código que funciona perfectamente, pero que en el runtime
de Microsoft
... casca (o directamente ¡no compila!).
En Desknote lo he solucionado buscando en la otra documentación y, haciendo cambios medio a ciegas (no tengo un Windows
a mano, las pruebas las hacía Felipe
en casa), conseguir que funcionara en Windows
.
Cualquiera que haya programado sabe lo frustrante que es buscar una forma de reescribir un trozo de código que funciona de otra manera, por un motivo poco claro :D.
Mis principales batallas han sido contra XmlDocument
y Process.Start
, pero en general era viable conseguirlo... y lo hemos conseguido :).
Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.