<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Pika-pika... Chuuuu</title><link>http://geeks.ms/blogs/aruiz/default.aspx</link><description>El blog variado sobre temas curiosos en .NET... Cubriendo un poco de todo ;)&lt;br /&gt;&lt;img src="http://geeks.ms/photos/aruiz/images/37189/original.aspx" alt="Augusto tiene esta pinta..." /&gt;</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Cadenas de conexión de Entity Framework... Cuidado!</title><link>http://geeks.ms/blogs/aruiz/archive/2009/11/13/cadenas-de-conexi-243-n-de-entity-framework-cuidado.aspx</link><pubDate>Fri, 13 Nov 2009 15:24:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:160448</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Hola a todos!&lt;/p&gt;
&lt;p&gt;Hoy voy a comentar algo bastante curioso con lo que me he topado trabajando con Entity Framework. A modo de pre&amp;aacute;mbulo, os dir&amp;eacute; que durante la ejecuci&amp;oacute;n de una aplicaci&amp;oacute;n, cada vez que instanci&amp;aacute;bamos un objeto de una clase que heredase de ObjectContext se lanzaban una serie de excepciones, cuyo n&amp;uacute;mero iba creciendo. Es decir, que simplemente invocando al constructor, sin conectarse a&amp;uacute;n a ning&amp;uacute;n sitio, pod&amp;iacute;amos ver c&amp;oacute;mo se lanzaban 2 excepciones. A la siguiente invocaci&amp;oacute;n&amp;nbsp;del constructor&amp;nbsp;(de la misma clase!) pod&amp;iacute;an lanzarse 3... Es decir, el n&amp;uacute;mero de excepciones iba &amp;quot;in crescendo&amp;quot;. Y aunque iban aumentando el n&amp;uacute;mero de excepciones por invocaci&amp;oacute;n de constructor, no hab&amp;iacute;a un patr&amp;oacute;n para poder determinar por qu&amp;eacute; iba aumentando ese n&amp;uacute;mero. O al menos el patr&amp;oacute;n no era aparente del todo (tranquilos que al final desenmascararemos el misterio).&lt;/p&gt;
&lt;p&gt;Por otro lado, para agravar m&amp;aacute;s a&amp;uacute;n la situaci&amp;oacute;n, los ObjectContext ten&amp;iacute;an una vida cort&amp;iacute;sima, y se creaban y destru&amp;iacute;an continuamente (arquitectura empresarial, acceso a datos desde componentes sin estado... bueno, os hac&amp;eacute;is a la idea, &amp;iquest;verdad?), con lo que el n&amp;uacute;mero de excepciones lanzadas era... enorme.&lt;/p&gt;
&lt;p&gt;Como a estas alturas ya sabr&amp;eacute;is, en las cadenas de conexi&amp;oacute;n de Entity Framework hay que indicar varios par&amp;aacute;metros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El proveedor de acceso a datos a utilizar&lt;/li&gt;
&lt;li&gt;La cadena de conexi&amp;oacute;n a base de datos (de las de ADO.NET de toda la vida) que usa el proveedor del punto anterior.&lt;/li&gt;
&lt;li&gt;D&amp;oacute;nde est&amp;aacute;n los ficheros de metadatos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para crear cadenas de conexi&amp;oacute;n mediante c&amp;oacute;digo, se recomienda utilizar la clase EntityConnectionStringBuilder, &lt;a href="http://msdn.microsoft.com/es-es/library/bb738533.aspx"&gt;tal y como se indica aqu&amp;iacute;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bien... Pues la causa de las excepciones era el c&amp;oacute;mo indic&amp;aacute;bamos d&amp;oacute;nde est&amp;aacute;n los metadatos. Los ficheros de metadatos los tenemos dentro de los ensamblados en los que tenemos definidas las entidades. Por lo tanto, la ubicaci&amp;oacute;n de los metadatos la est&amp;aacute;bamos indicando de la siguiente manera:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier;"&gt;res://*/MyEntities.csdl|res://*/MyEntities.ssdl|res://*/MyEntities.msl&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Que quiere decir: Busca en los recursos del ensamblado &amp;quot;*&amp;quot; (es decir, en todos los ensamblados), un recurso que se llame &amp;quot;MyEntities.csdl&amp;quot; (modelo conceptual), otro que se llame &amp;quot;MyEntities.ssdl&amp;quot; (modelo de almacenamiento) y otro que se llame &amp;quot;MyEntities.msl&amp;quot; (mappings).&lt;/p&gt;
&lt;p&gt;En casos normales, la b&amp;uacute;squeda de esos metadatos no deber&amp;iacute;a dar ning&amp;uacute;n problema. La b&amp;uacute;squeda de los metadatos (&lt;a href="http://msdn.microsoft.com/es-es/library/cc716756.aspx"&gt;seg&amp;uacute;n el MSDN&lt;/a&gt;) se lleva a cabo de la siguiente forma:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Busca el recurso indicado en el ensamblado que realiza la llamada&lt;/li&gt;
&lt;li&gt;Busca el recurso indicado en los ensamblados referenciados desde el ensamblado del punto anterior&lt;/li&gt;
&lt;li&gt;Busca el recurso indicado en los ensamblados que se encuentran en la carpeta de trabajo de la aplicaci&amp;oacute;n&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Esta informaci&amp;oacute;n no es incorrecta, pero es incompleta. La b&amp;uacute;squeda de los recursos se lleva a cabo utilizando la misma t&amp;aacute;ctica que cuando se debe localizar un ensamblado concreto. Es decir, que el tercer paso ser&amp;iacute;a m&amp;aacute;s bien as&amp;iacute;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Busco en los ensamblados cargados en el dominio de aplicaci&amp;oacute;n&lt;/li&gt;
&lt;li&gt;Busco en los ensamblados de la carpeta de trabajo actual&lt;/li&gt;
&lt;li&gt;Busco en los ensamblados de la Global Assembly Cache (GAC).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto creo que es as&amp;iacute; por la excepci&amp;oacute;n que me lanzaban los constructores de las clases derivadas de ObjectContext. La excepci&amp;oacute;n en concreto era la siguiente:&lt;/p&gt;
&lt;p&gt;Ocurri&amp;oacute; NotSupportedException: No se admite el miembro invocado en un ensamblado din&amp;aacute;mico.&lt;/p&gt;
&lt;p&gt;Y la pila de llamadas era la siguiente:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier;"&gt;&lt;strong&gt;mscorlib.dll!System.Reflection.Emit.AssemblyBuilder.GetManifestResourceNames()&lt;/strong&gt; + 0x39 bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.GetManifestResourceNamesForAssembly(System.Reflection.Assembly assembly) + 0x24 bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.AssemblyContainsResource(System.Reflection.Assembly assembly, ref string resourceName = &amp;quot;MyEntities.csdl&amp;quot;) + 0x22 bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.LoadResources(string assemblyName, string resourceName, System.Collections.Generic.ICollection&amp;lt;string&amp;gt; uriRegistry = Count = 0, System.Data.Metadata.Edm.MetadataArtifactAssemblyResolver resolver = {System.Data.Metadata.Edm.DefaultAssemblyResolver}) + 0x91 bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.CreateResourceLoader(string path, System.Data.Metadata.Edm.MetadataArtifactLoader.ExtensionCheck extensionCheck, string validExtension, System.Collections.Generic.ICollection&amp;lt;string&amp;gt; uriRegistry, System.Data.Metadata.Edm.MetadataArtifactAssemblyResolver resolver) + 0xba bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Metadata.Edm.MetadataArtifactLoader.Create(string path, System.Data.Metadata.Edm.MetadataArtifactLoader.ExtensionCheck extensionCheck, string validExtension, System.Collections.Generic.ICollection&amp;lt;string&amp;gt; uriRegistry, System.Data.Metadata.Edm.MetadataArtifactAssemblyResolver resolver) + 0x40 bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.EntityClient.EntityConnection.SplitPaths(string paths) + 0x294 bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.EntityClient.EntityConnection.GetMetadataWorkspace(bool initializeAllCollections = false) + 0x95 bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Objects.ObjectContext.RetrieveMetadataWorkspaceFromConnection() + 0x1b bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Objects.ObjectContext.ObjectContext(System.Data.EntityClient.EntityConnection connection, bool isConnectionConstructor = false) + 0xad bytes&lt;br /&gt;
System.Data.Entity.dll!System.Data.Objects.ObjectContext.ObjectContext(string connectionString, string defaultContainerName = &amp;quot;MyEntities&amp;quot;) + 0x1c bytes&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Es decir... que fallaba en el m&amp;eacute;todo GetManifestResourceNames, quej&amp;aacute;ndose de que ese m&amp;eacute;todo no est&amp;aacute; soportado cuando se invoca sobre un ensamblado din&amp;aacute;mico. El ensamblado llamador no era din&amp;aacute;mico, de eso estoy seguro. As&amp;iacute; como que estoy seguro de que no hab&amp;iacute;a ensamblados din&amp;aacute;micos ni como referencia del ensamblado que lo llamaba, ni en la carpeta bin. &lt;strong&gt;Pero s&amp;iacute; que los hab&amp;iacute;a en el dominio de aplicaci&amp;oacute;n&lt;/strong&gt; (AppDomain), con lo cual, a la hora de localizar los recursos, estaba buscando en los ensamblados ya cargados en el AppDomain, y lo estaba haciendo &lt;strong&gt;antes&lt;/strong&gt; de mirar en los ensamblados del directorio de trabajo, ya que si no, habr&amp;iacute;a localizado los recursos sin problemas.&lt;/p&gt;
&lt;p&gt;El hecho de que el n&amp;uacute;mero de excepciones por constructor fuera aumentando quedaba resuelto de manera sencilla. Seg&amp;uacute;n se fuesen generando m&amp;aacute;s ensamblados din&amp;aacute;micos y se fuesen cargando en el AppDomain, se lanzaba una excepci&amp;oacute;n por cada ensamblado din&amp;aacute;mico en el AppDomain en cada invocaci&amp;oacute;n del constructor.&lt;/p&gt;
&lt;p&gt;Vale, ya s&amp;eacute; que generar ensamblados din&amp;aacute;micamente (Reflection.Emit) no es algo que se haga todos los d&amp;iacute;as. Pero me ha hecho pensar un poco en c&amp;oacute;mo escribir las cadenas de conexi&amp;oacute;n para que .NET vaya directamente al ensamblado que tiene incrustados los recursos, y no se de un garbeo cargando todos los assemblies del lugar para buscar un recurso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Corolario&lt;/strong&gt;:&amp;nbsp;Cuando especifiques una cadena de conexi&amp;oacute;n de Entity Framework, si est&amp;aacute; incrustada como recurso en un ensamblado (que es la opci&amp;oacute;n por defecto), indica siempre el nombre del ensamblado donde est&amp;aacute; ese recurso. &amp;iexcl;Huye de los asteriscos, no suelen ser buenos compa&amp;ntilde;eros! (&lt;i&gt;y si no, se lo preguntas al que hizo un &lt;/i&gt;&lt;span style="font-family:courier;"&gt;&lt;i&gt;rm -rf *&lt;/i&gt;&lt;/span&gt;&lt;i&gt; sobre &lt;/i&gt;&lt;span style="font-family:courier;"&gt;&lt;i&gt;/&lt;/i&gt;&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:courier;"&gt;Metadata=res://&amp;lt;assemblyFullName&amp;gt;/&amp;lt;resourceName&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P.D.&lt;/strong&gt;: Aunque en la documentaci&amp;oacute;n diga que tienes que poner el nombre completo del ensamblado, en realidad no es as&amp;iacute;. No es necesario especificar la versi&amp;oacute;n, ni la cultura, ni la clave p&amp;uacute;blica del ensamblado...&lt;/p&gt;
&lt;p&gt;Si sigo as&amp;iacute;, la pr&amp;oacute;xima entrada ser&amp;aacute; en el 2012... Saludos a todos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=160448" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>IDictionary no es serializable usando IXmlSerializable...</title><link>http://geeks.ms/blogs/aruiz/archive/2008/01/10/idictionary-no-es-serializable-usando-ixmlserializable.aspx</link><pubDate>Thu, 10 Jan 2008 15:15:52 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:62789</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=62789</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=62789</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2008/01/10/idictionary-no-es-serializable-usando-ixmlserializable.aspx#comments</comments><description>&lt;p&gt;Hola!&lt;/p&gt; &lt;p&gt;Tengo una confesión hoy. Me encanta usar la clase genérica &lt;a href="http://msdn2.microsoft.com/en-us/library/xfhwa508.aspx" target="_blank"&gt;Dictionary&lt;/a&gt;. Cuando necesito organizar una caché que pueda ser accedida a la velocidad del rayo, y con claves no necesariamente sencillas, ¡Zas! Dictionary que te crió. Sin embargo, la clase genérica Dictionary implementa la interfaz &lt;a href="http://msdn2.microsoft.com/en-us/library/system.collections.idictionary.aspx" target="_blank"&gt;IDictionary&lt;/a&gt;, y no se puede serializar usando &lt;a href="http://msdn2.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx" target="_blank"&gt;IXmlSerializable&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Y... ¿a quién le importa esto? Pues... teniendo en cuenta que IXmlSerializable es la interfaz mediante la cual se serializan los objetos cuando se van a usar Web Services no-WCF (WCF utiliza &lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx" target="_blank"&gt;DataContractSerializer&lt;/a&gt;), la cosa parece ya un poco más importante...&lt;/p&gt; &lt;p&gt;Si lo pensamos un momento, serializar un diccionario a XML no es más complicado que tomar las claves y los valores, y plantarlos en un XML. A la hora de deserializar, vas metiendo cada elemento con su clave en el diccionario y listos... Entonces... ¿por qué no se puede serializar usando IXmlSerializable?&lt;/p&gt; &lt;p&gt;La respuesta a esta pregunta la da &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=509350&amp;amp;SiteID=1" target="_blank"&gt;Kim Hamilton (de Microsoft) en los foros&lt;/a&gt;. Básicamente dice que la clase Dictionary es parte de mscorlib.dll y la interfaz IXmlSerializable está definida en System.Xml.dll. Para evitar una referencia circular, el diccionario no se serializa, y listos...&lt;/p&gt; &lt;p&gt;Pues vaya, no?&lt;/p&gt; &lt;p&gt;Por suerte, la gente no es que esté muy contenta con esto, y hay alguna implementación de diccionarios que sí que son serializables, y son tan flexibles como el Dictionary que viene en el framework. Por ejemplo, &lt;a href="http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx" target="_blank"&gt;ésta&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Si estás creando Web Services con WCF, entonces no tendrás problemas, ya que DataContractSerializer serializa sin problemas los diccionarios.&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=62789" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Serializaci_26002300_243_3B00_n/default.aspx">Serializaci&amp;#243;n</category></item><item><title>XML no es la solución universal...</title><link>http://geeks.ms/blogs/aruiz/archive/2008/01/02/soa-no-es-la-soluci-243-n.aspx</link><pubDate>Wed, 02 Jan 2008 10:59:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:60751</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=60751</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=60751</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2008/01/02/soa-no-es-la-soluci-243-n.aspx#comments</comments><description>&lt;p&gt;...pero es un buen comienzo (aunque, como todo, depende de para qué).&lt;/p&gt;
&lt;p&gt;Llevo varias semanas rumiando esta idea, y la verdad es que me ganaré las iras de más de uno al expresarla en público, pero da igual. Así además podré sondear las ideas de los cracks que por aquí suelen pasar.&lt;/p&gt;
&lt;p&gt;Después de llevar ya un buen tiempo trabajando con Web Services, hay una idea que siempre pasa por mi cabeza de manera recurrente. ¿Por qué XML para el intercambio de datos?&lt;/p&gt;
&lt;p&gt;Sé que SOA no es lo mismo que XML/XSD, pero en el 95% de los casos suelen ir de la mano para la comunicación de datos entre diversos sistemas. Y mi pregunta es ¿por qué?. Parte de las respuestas que me vienen a la cabeza son las siguientes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XML es un lenguaje extensible, y muy flexible, y XSD nos permite definir cualquier estructura de datos que necesitemos.&lt;/li&gt;
&lt;li&gt;Es fácil de comprender por los desarrolladores.&lt;/li&gt;
&lt;li&gt;Es fácil de manipular por parte de los desarrolladores.&lt;/li&gt;
&lt;li&gt;Al ser una representación textual de los datos, podemos examinar los contenidos de los datos de forma sencilla a la hora de depurar&lt;/li&gt;
&lt;li&gt;Nos independizamos de las representaciones internas de los datos de cada uno de los sistemas.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Bueno, como podéis ver, la&amp;nbsp;quinta razón no es del todo cierta, ya que si por ejemplo queréis&amp;nbsp;consumir un servicio web creado con otra tecnología que no sea .NET desde una aplicación .NET veremos que cuando determinados tipos de datos aparecen en escena (por ejemplo, fechas), es posible que nos encontremos con algún problema.&lt;/p&gt;
&lt;p&gt;Y hay&amp;nbsp;algo más&amp;nbsp;que salta a la vista tras ver las razones expuestas (si bien es una visión algo sesgada): El foco está puesto en el desarrollador, no en los sistemas que tienen que intercambiar los datos entre sí.&lt;/p&gt;
&lt;p&gt;La duda que se me plantea es: ¿Por qué usamos un formato de datos comprensible por los humanos cuando los que tienen que manipular esos datos son sistemas informáticos? (es decir, máquinas). Los datos en XML llevan asociados una merma de rendimiento derivada del procesamiento que hay que hacer antes de poderlos utilizar nada despreciable. Y también se usa más espacio del que se podría utilizar, incrementando el gasto de ancho de banda para las comunicaciones.&lt;/p&gt;
&lt;p&gt;Creo que sería más interesante algo como lo siguiente: Al igual que tenemos los XSD para definir los XML, ¿no podríamos definir un lenguaje del estilo de XSD que lo que defina es un formato &lt;strong&gt;binario&lt;/strong&gt; de datos &lt;strong&gt;de forma sencilla&lt;/strong&gt;? Es decir, &lt;strong&gt;el lenguaje que define los datos&lt;/strong&gt; a intercambiar &lt;strong&gt;debería ser fácil de comprender&lt;/strong&gt; por los desarrolladores, pero las estructuras de datos que representa deberían ser mucho más compactas y eficientes. Y sin dejar huecos para las imprecisiones. Cada tipo de dato &amp;quot;simple&amp;quot; - fechas, cadenas de texto, datos numéricos - debería tener definida su representación en binario. Por ejemplo, podríamos definir que las cadenas de texto están representadas mediante Unicode, ANSI Z, etc. O si queremos que los datos utilicen big-endian o little endian...&lt;/p&gt;
&lt;p&gt;Por supuesto, debería tener la posibilidad de hacer includes, y referencias a objetos, de manera que cada tipo de datos &amp;quot;complejo&amp;quot; pueda ser definido una única vez, y cada instancia pueda ser serializada también de manera única.&lt;/p&gt;
&lt;p&gt;Esto requiriría un apoyo por parte de las herramientas de desarrollo, de manera que a la hora de depurar tomasen la estructura de datos a examinar, y utilizando el lenguaje de definición mostrase al desarrollador los datos de una manera sencilla de comprender y manipular.&lt;/p&gt;
&lt;p&gt;Quizá con algo así, podríamos tener un &amp;quot;Biztalk&amp;quot; que no necesitase tanto maquinón para ejecutarse... ^_^U&lt;/p&gt;
&lt;p&gt;¿Qué opináis al respecto?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=60751" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Opini_26002300_243_3B00_n/default.aspx">Opini&amp;#243;n</category></item><item><title>Una chorradita, pero que queda muy molona...</title><link>http://geeks.ms/blogs/aruiz/archive/2007/11/02/una-chorradita-pero-que-queda-muy-molona.aspx</link><pubDate>Fri, 02 Nov 2007 10:02:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:47466</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=47466</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=47466</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/11/02/una-chorradita-pero-que-queda-muy-molona.aspx#comments</comments><description>&lt;p&gt;Buenas!&lt;/p&gt; &lt;p&gt;En este artículo vamos a crear un formulario que muestre un mensaje de espera, por si tenemos que hacer una tarea que requiera tiempo, para distraer un poco al usuario. Además vamos a realizar un fundido del formulario, para que aparezca poco a poco.&lt;/p&gt; &lt;p&gt;En este ejemplo vamos a utilizar multithreading, al estilo de lo comentado &lt;a href="http://geeks.ms/blogs/aruiz/archive/2006/11/16/p-rtate-bien-con-tu-interfaz-de-usuario.aspx"&gt;en este artículo&lt;/a&gt;, (no me preguntéis dónde está el código fuente de este artículo, porque pese a que los adjuntos están en el servidor - no sé dónde - no se muestran en los artículos - ayudaaa!).&lt;/p&gt; &lt;p&gt;Antes de entrar en la chicha, unos pocos preparativos:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Vamos a crear un nuevo formulario en nuestro proyecto. Le llamaremos &lt;font face="courier new"&gt;FrmEspera&lt;/font&gt;.  &lt;li&gt;A este formulario le quitamos el borde (&lt;font face="courier new"&gt;FormBorderStyle=None&lt;/font&gt;).  &lt;li&gt;Además, le&amp;nbsp;quitamos el texto (&lt;font face="courier new"&gt;Text=&amp;quot;&amp;quot;&lt;/font&gt;). Así conseguiremos que se oculte completamente el borde del mismo, quedando como un panel flotante.  &lt;li&gt;Por último, establecemos la propiedad &lt;font face="courier new"&gt;StartPosition=CenterScreen&lt;/font&gt;, para que cuando mostremos el formulario aparezca siempre en el centro de la pantalla.  &lt;li&gt;Para que quede bonito, le ponemos una imagen de fondo al formulario, un control &lt;font face="courier new"&gt;PictureBox&lt;/font&gt; para mostrar un icono, y una etiqueta (control &lt;font face="courier new"&gt;Label&lt;/font&gt;).&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Ahora, vamos al grano: Sería interesante poder modificar el texto a mostrar en el formulario (para usarlo en diferentes situaciones), y la imagen a mostrar. Para esto, en el código del formulario declaramos un par de propiedades:&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; ImagenAMostrar() &lt;span class="kwrd"&gt;As&lt;/span&gt; Image&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;Return&lt;/span&gt; pictureBox1.Image&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Set&lt;/span&gt;(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; value &lt;span class="kwrd"&gt;As&lt;/span&gt; Image)&lt;/pre&gt;&lt;pre&gt;      pictureBox1.Image = value&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Set&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; MensajeAMostrar() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;      &lt;span class="kwrd"&gt;Return&lt;/span&gt; label1.Text&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Set&lt;/span&gt;(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; value &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;      label1.Text = value&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Set&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; Property&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Como vamos a utilizar varios hilos, vamos a crear un tipo delegado que nos va a permitir invocar desde el hilo en el que vamos&amp;nbsp;a controlar el cambio de la opacidad&amp;nbsp;del formulario el método que realmente cambiará la opacidad del mismo. Esto es necesario para evitar excepciones derivadas del hecho de cambiar una propiedad de un formulario desde un hilo diferente a aquél en el que se creó.&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Delegate&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; SetOpacityDelegate(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; op &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Double&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;Private&lt;/span&gt; dlg &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SetOpacityDelegate(&lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.SetOpacity)&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; SetOpacity(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; op &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Double&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Me&lt;/span&gt;.BringToFront()&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Opacity = op&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="rem"&gt;&amp;#39; Esto es feo, pero necesitamos que se procesen los eventos pendientes...&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   Application.DoEvents()&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;If&lt;/span&gt; op = 0.0F &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;      &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Close()&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Por último, vamos a crear los métodos que usaremos para mostrar y ocultar el formulario. Les vamos a llamar &lt;font face="courier new"&gt;FadeIn&lt;/font&gt; y &lt;font face="courier new"&gt;FadeOut&lt;/font&gt;:&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; FadeIn()&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Opacity = 0.0F&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Show()&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Dim&lt;/span&gt; dlg &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.Threading.ThreadStart(&lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.doFadeIn)&lt;/pre&gt;&lt;pre class="alt"&gt;   dlg.Invoke()&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; FadeOut()&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Dim&lt;/span&gt; dlg &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.Threading.ThreadStart(&lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.doFadeOut)&lt;/pre&gt;&lt;pre&gt;   dlg.Invoke()&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; doFadeIn()&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;For&lt;/span&gt; op &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Double&lt;/span&gt; = 0.1F &lt;span class="kwrd"&gt;To&lt;/span&gt; 1.0F &lt;span class="kwrd"&gt;Step&lt;/span&gt; 0.1F&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;If&lt;/span&gt; InvokeRequired &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;         &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Invoke(dlg, op)&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;Else&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;         &lt;span class="kwrd"&gt;Me&lt;/span&gt;.SetOpacity(op)&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;      System.Threading.Thread.Sleep(50)&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Next&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Invoke(dlg, 1.0F)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; doFadeOut()&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;For&lt;/span&gt; op &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Double&lt;/span&gt; = 1.0F &lt;span class="kwrd"&gt;To&lt;/span&gt; 0.1F &lt;span class="kwrd"&gt;Step&lt;/span&gt; -0.1F&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;If&lt;/span&gt; InvokeRequired &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;         &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Invoke(dlg, op)&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;Else&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;         &lt;span class="kwrd"&gt;Me&lt;/span&gt;.SetOpacity(op)&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;      System.Threading.Thread.Sleep(50)&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Next&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Invoke(dlg, 0.0F)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Como podemos ver, en el método &lt;font face="courier new"&gt;FadeIn&lt;/font&gt; y en el método &lt;font face="Courier New"&gt;FadeOut&lt;/font&gt;, hacemos prácticamente lo mismo: Inicializamos un hilo que llamará al método que se encarga de realizar un bucle variando la opacidad del formulario. Y en este método hacemos un bucle en el que se comprueba si estamos en el hilo de la interfaz de usuario o en otro (llamando a &lt;font face="Courier New"&gt;InvokeRequired&lt;/font&gt;), si bien no es necesario hacerlo, ya que esa condición siempre será verdadera por cómo llamamos a los métodos &lt;font face="Courier New"&gt;doFadeIn&lt;/font&gt; y &lt;font face="Courier New"&gt;doFadeOut&lt;/font&gt;, y se llama al método que cambia la opacidad a través de un delegado si estamos en un hilo diferente, o directamente si estamos en el hilo de la interfaz de usuario.&lt;/p&gt;
&lt;p&gt;¿Cómo usaríamos este formulario? Pues de la siguiente manera:&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Dim&lt;/span&gt; frmMsg &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; FrmEspera&lt;/pre&gt;&lt;pre&gt;frmMsg.MensajeAmostrar = &lt;span class="str"&gt;&amp;quot;Por favor, espere. Estoy haciendo algo MUY importante&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;frmMsg.ImagenAMostrar = &lt;span class="kwrd"&gt;Me&lt;/span&gt;.ImageList1.Images(&lt;span class="str"&gt;&amp;quot;ImagenEspera&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;frmMsg.FadeIn()&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;&amp;#39; Hacemos la tarea pesada aquí...&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;frmMsg.FadeOut()&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bueno... Pues eso es todo por hoy.&lt;/p&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=47466" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Windows+Forms/default.aspx">Windows Forms</category></item><item><title>Hagamos recuento...</title><link>http://geeks.ms/blogs/aruiz/archive/2007/11/02/hagamos-recuento.aspx</link><pubDate>Fri, 02 Nov 2007 09:11:09 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:47462</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=47462</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=47462</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/11/02/hagamos-recuento.aspx#comments</comments><description>&lt;p&gt;Hola,&lt;/p&gt; &lt;p&gt;Hace ya poco más de un año, este blog se inauguró con &lt;a href="http://geeks.ms/blogs/aruiz/archive/2006/10/30/Databinding-con-WinForms-y-el-DataGridView_3A00_-Navegando-objetos.aspx" target="_blank"&gt;este post&lt;/a&gt;. Desde entonces se han recogido&amp;nbsp;36.232 visitas. Con un total de 46 artículos,&amp;nbsp;se han producido&amp;nbsp;214 comentarios, una media de 4,7 comentarios por artículo (si bien esto no es lo habitual). Esta media es superior a lo que debería haber sido, principalmente a causa de un par de artículos que fueron en su día polémicos (&lt;a href="http://geeks.ms/blogs/aruiz/archive/2006/11/10/La-diferencia-entre-un-m_E900_dico-y-un-inform_E100_tico.aspx" target="_blank"&gt;éste&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/aruiz/archive/2006/11/08/Los-punteros-y-la-POO-_2800_o-por-qu_E900_-hay-que-aprender-C_2900_.aspx" target="_blank"&gt;éste&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;De todas maneras, ha sido un año complicado, que se ha notado en la cantidad de artículos publicados por mes, pero haciendo balance, creo que ha sido positivo.&lt;/p&gt; &lt;p&gt;Muchas gracias a todos los que participáis, bien sea leyendo o haciendo comentarios.&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=47462" width="1" height="1"&gt;</description></item><item><title>III Conferencia de Usuarios de Sharepoint</title><link>http://geeks.ms/blogs/aruiz/archive/2007/10/22/iii-conferencia-de-usuarios-de-sharepoint.aspx</link><pubDate>Mon, 22 Oct 2007 07:46:24 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:44336</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=44336</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=44336</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/10/22/iii-conferencia-de-usuarios-de-sharepoint.aspx#comments</comments><description>&lt;p&gt;La empresa para la que trabajo (Informática El Corte Inglés) va a participar como patrocinador Oro en la III Conferencia de Usuarios de Sharepoint, que se celebrará el 30 de octubre en el Hotel Meliá Castilla, sito en la calle Capitán Haya, 43, en Madrid.&lt;/p&gt; &lt;p&gt;En esta conferencia se hará una presentación de un proyecto bastante interesante, con el que se ha alcanzado la certificación oficial &amp;quot;AA&amp;quot; de Accesibilidad.&lt;/p&gt; &lt;p&gt;Podéis consultar la agenda del evento aquí:&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.microsoft.com/spain/office/ceus/agenda/default.mspx" href="http://www.microsoft.com/spain/office/ceus/agenda/default.mspx"&gt;http://www.microsoft.com/spain/office/ceus/agenda/default.mspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Y podéis inscribiros aquí:&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.microsoft.com/spain/office/ceus/default.mspx" href="http://www.microsoft.com/spain/office/ceus/default.mspx"&gt;http://www.microsoft.com/spain/office/ceus/default.mspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=44336" width="1" height="1"&gt;</description></item><item><title>Mi aplicación en C++ (VC++ 2005 Express) no se ejecuta en otros equipos!!! (solución)</title><link>http://geeks.ms/blogs/aruiz/archive/2007/10/19/mi-aplicaci-243-n-en-c-vc-2005-express-no-se-ejecuta-en-otros-equipos-soluci-243-n.aspx</link><pubDate>Fri, 19 Oct 2007 11:32:35 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:43664</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>22</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=43664</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=43664</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/10/19/mi-aplicaci-243-n-en-c-vc-2005-express-no-se-ejecuta-en-otros-equipos-soluci-243-n.aspx#comments</comments><description>&lt;p&gt;Hola a todos!&lt;/p&gt; &lt;p&gt;Como ya he comentado en &lt;a href="http://geeks.ms/blogs/aruiz/archive/2007/02/13/mis-experiencias-con-visual-c-2005-express.aspx" target="_blank"&gt;otra ocasión&lt;/a&gt;, estoy usando el Visual C++ 2005 Express para desarrollar un jueguecillo con OpenGL y SDL. Cuando empecé, lo estaba desarrollando con el Visual C++ 2003, pero me comentaron que la STL había mejorado en la versión 2005, y como había una versión gratuita, decidí actualizarme.&lt;/p&gt; &lt;p&gt;El caso es que el otro día decidí liberar una alpha para los betatesters. Y de repente algunos (no todos) me comentaron que no funcionaba. Que les daba el siguiente error:&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;No se pudo iniciar la aplicacion porque su configuracion es incorrecta. Reinstalar la aplicacion puede solucionar el problema.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="v" size="2"&gt;Hmmm... Al principio pensé que debía haber algún problema con mi código. Así que empece a meter trazas y pedir logs. Tras comentarme los betatesters que no había ningún log, me di cuenta de que la aplicación, &lt;em&gt;como dice el error claramente&lt;/em&gt;, no llegaba a iniciarse. ^_^U&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;Entonces me di cuenta de un pequeño detalle. El runtime de C de esta versión de C++ probablemente no lo tenían todos los usuarios. Googleando un poco, ví que los betatesters se podían instalar el &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=32bc1bee-a3f9-4c13-9c99-220b62a191ee&amp;amp;displaylang=en" target="_blank"&gt;paquete de distribución del runtime de C++&lt;/a&gt;... Pero me pareció que iba a ser un rollo para ellos tener que andar instalando nada para probar una alpha.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;¿Qué hago? Si no quiero que se instalen el paquete de distribución, tampoco me voy a poner a generar un msi con la alpha del juego. Habría sido la mejor solución, pero generalmente la gente prefiere descomprimir el archivo, y ejecutar directamente, sobre todo cuando algo es no definitivo...&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="2"&gt;Finalmente, encontré &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=164465&amp;amp;SiteID=1" target="_blank"&gt;la solución en los foros de microsoft&lt;/a&gt;. La traduzco a continuación:&lt;/font&gt;&lt;/p&gt; &lt;p&gt;1) En la máquina en la que tienes instalado Visual C++ Express, crea la siguiente carpeta y subcarpetas colgando de %PROGRAMFILES%\Microsoft Visual Studio 8\VC &lt;p&gt;redist\x86\Microsoft.VC80.CRT &lt;p&gt;2) Copia msvcr80.dll, msvcp80.dll, msvcm80.dll&amp;nbsp;de:&lt;/p&gt; &lt;p&gt;%WINDIR%\winsxs\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd &lt;/p&gt; &lt;p&gt;a:  &lt;p&gt;%PROGRAMFILES%\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT  &lt;p&gt;3) En&amp;nbsp;la carpeta&amp;nbsp;Microsoft.VC80.CRT, crea un nuevo fichero llamado:  &lt;p&gt;Microsoft.VC80.CRT.manifest  &lt;p&gt;4) Dicho fichero deberá tener el siguiente contenido: &lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UTF-8&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;standalone&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;yes&amp;quot;&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;&amp;lt;!-- Copyright © 1981-2001 Microsoft Corporation --&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;assembly&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;urn:schemas-microsoft-com:asm.v1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;manifestVersion&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;noInheritable&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;assemblyIdentity&lt;/span&gt;
      &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;win32&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.VC80.CRT&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;8.0.50608.0&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;processorArchitecture&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x86&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;publicKeyToken&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1fc8b3b9a1e18e3b&amp;quot;&lt;/span&gt;
    &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;file&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;msvcr80.dll&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;file&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;msvcp80.dll&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;file&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;msvcm80.dll&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;assembly&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Con esto hemos creado un nuevo directorio en tu instalación de Visual C++ Express&amp;nbsp;que puede ser reutilizado siempre que lo necesites.
&lt;p&gt;Para distribuir estos ficheros, simplemente copia&amp;nbsp;la carpeta&amp;nbsp;Microsoft.VC80.CRT en la carpeta de tu programa.&amp;nbsp;Y eso es todo.&amp;nbsp;Así que, por ejemplo, si el ejecutable de tu aplicación está en la ruta:
&lt;p&gt;%PROGRAMFILES%\MiAplicación
&lt;p&gt;tendrás una&amp;nbsp;carpeta llamada: 
&lt;p&gt;%PROGRAMFILES%\MiAplicación\Microsoft.VC80.CRT 
&lt;p&gt;que contendrá los cuatro ficheros mencionados anteriormente (3 DLLs, y el manifiesto que has creado a mano). 
&lt;p&gt;No hace falta instalar nada más. Simplemente arranca tu aplicación, y se ejecutará sin problemas. No hace falta ninguna instalación específica. Simplemente basta con que tu programa de instalación cree esa subcarpeta junto con el resto de archivos que tenga tu aplicación.&lt;/p&gt;
&lt;p&gt;NOTA: &lt;/p&gt;
&lt;p&gt;%WINDIR% es el directorio en el que está instalado Windows. Es una variable que se puede utilizar en el cmd.exe. Normalmente es C:\WINDOWS&lt;/p&gt;
&lt;p&gt;%PROGRAMFILES% es similar, salvo que apunta a la carpeta Archivos de Programa. Lo bueno es que es independiente de idioma.&lt;/p&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=43664" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Visual+C_2B002B00_+2005+Express/default.aspx">Visual C++ 2005 Express</category></item><item><title>Aprieta, aprieta, que entra más...</title><link>http://geeks.ms/blogs/aruiz/archive/2007/10/15/aprieta-aprieta-que-entra-m-225-s.aspx</link><pubDate>Mon, 15 Oct 2007 12:00:48 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:41934</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=41934</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=41934</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/10/15/aprieta-aprieta-que-entra-m-225-s.aspx#comments</comments><description>&lt;p&gt;No os llevéis a confusión con el título... Este artículo no es más que un mini-tutorial&amp;nbsp;sobre la clase &lt;a href="http://msdn2.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx" target="_blank"&gt;System.IO.Compression.GZipStream&lt;/a&gt;, que nos proporciona la funcionalidad necesaria para comprimir datos utilizando el estándar &amp;quot;de facto&amp;quot; &lt;a href="http://www.gzip.org/" target="_blank"&gt;gzip&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;La verdad es que el uso de esta clase no debería ser complicado, ya que básicamente lo que hacemos es leer y escribir datos de un stream, como si fuese un fichero o un trozo de memoria más. Pero tiene una pequeña particularidad: Para que funcione correctamente nuestro código tenemos que tener cuidado de indicar en el constructor que queremos que el stream subyacente a nuestro GZipStream se quede abierto cuando terminemos de utilizarlo. Sobre todo cuando lo que queremos es comprimir en memoria, para posteriormente, sin&amp;nbsp;crear ficheros temporales en&amp;nbsp;el disco duro, enviarlo por red.&lt;/p&gt; &lt;p&gt;Veamos el ejemplo, sencillo, sencillo:&lt;/p&gt; &lt;p&gt;Para comprimir:&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Dim&lt;/span&gt; memStream &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.IO.MemoryStream&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; Aquí está el quid de la cuestión: Indicarle en el tercer parámetro&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="rem"&gt;&amp;#39; que cuando cierre el stream de compresión, no elimine el stream&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; subyacente.&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Dim&lt;/span&gt; gzip &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.IO.Compression.GZipStream(memStream, _&lt;/pre&gt;&lt;pre&gt;                   IO.Compression.CompressionMode.Compress, &lt;span class="kwrd"&gt;True&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="kwrd"&gt;Dim&lt;/span&gt; fileBytes() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Byte&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   &lt;span class="kwrd"&gt;Dim&lt;/span&gt; compressedFileBytes() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Byte&lt;/span&gt; = {}&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; Leemos el contenido del fichero a comprimir&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   fileBytes = System.IO.File.ReadAllBytes(filePath)&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; Escribimos en el stream compresor&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   gzip.Write(fileBytes, 0, fileBytes.Length)&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; Si no cerramos el stream, no podremos leer correctamente el &lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="rem"&gt;&amp;#39; resultado de la compresión.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   gzip.Close()&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; Vamos a leer los datos comprimidos&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   Array.Resize(compressedFileBytes, memStream.Position)&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; Colocamos el stream de memoria al inicio, para leer todo.&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   memStream.Position = 0&lt;/pre&gt;&lt;pre&gt;   &lt;span class="rem"&gt;&amp;#39; Ya tenemos todos los datos en el array compressedFileBytes.&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   memStream.Read(compressedFileBytes, 0, compressedFileBytes.Length)&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="rem"&gt;&amp;#39; Hacer lo que queramos con los bytes comprimidos...&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="rem"&gt;&amp;#39; Y finalmente, limpiar un poquito.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;   memStream.Close()&lt;/pre&gt;&lt;pre class="alt"&gt;   gzip.Dispose()&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Para descomprimir:&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;  &lt;span class="rem"&gt;&amp;#39; fileBytes es un array de bytes que contiene el fichero comprimido&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;Dim&lt;/span&gt; memStream &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.IO.MemoryStream(fileBytes)&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="rem"&gt;&amp;#39; Creamos el GZipStream basándonos en el stream de memoria.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;Dim&lt;/span&gt; gzip &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.IO.Compression.GZipStream(memStream, _&lt;/pre&gt;&lt;pre class="alt"&gt;                   IO.Compression.CompressionMode.Decompress)&lt;/pre&gt;&lt;pre&gt;  &lt;span class="rem"&gt;&amp;#39; Si sabemos a priori el tamaño del fichero sin comprimir, &lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="rem"&gt;&amp;#39; inicializamos el array de bytes que contendrá el fichero&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="rem"&gt;&amp;#39; descomprimido.&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;Dim&lt;/span&gt; realFileBytes(fileSize - 1) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Byte&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;  memStream.Position = 0&lt;/pre&gt;&lt;pre&gt;  &lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="rem"&gt;&amp;#39; Leemos el fichero.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  gzip.Read(realFileBytes, 0, fileSize)&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="rem"&gt;&amp;#39; Cerramos...&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  gzip.Close()&lt;/pre&gt;&lt;pre class="alt"&gt;  gzip.Dispose()&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="rem"&gt;&amp;#39; Usamos el fichero para lo que queramos, está en el memoryStream...&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="rem"&gt;&amp;#39; Cerramos el MemoryStream.&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  memStream.Close()&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=41934" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category></item><item><title>Una técnica interesante para "ajustar" imágenes</title><link>http://geeks.ms/blogs/aruiz/archive/2007/10/03/una-t-233-cnica-interesante-para-quot-ajustar-quot-im-225-genes.aspx</link><pubDate>Wed, 03 Oct 2007 16:48:23 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:39296</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=39296</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=39296</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/10/03/una-t-233-cnica-interesante-para-quot-ajustar-quot-im-225-genes.aspx#comments</comments><description>&lt;p&gt;Iba a poner &amp;quot;para redimensionar imágenes&amp;quot;, pero realmente no es eso lo que hace. Lo interesante de esta técnica es que cuando reduces la imagen, lo que hace es eliminar la parte de la imagen que no nos proporciona información interesante. Y funciona bastante bien.&lt;/p&gt; &lt;p&gt;A esta técnica la llaman &amp;quot;Seam Carving&amp;quot;.&lt;/p&gt; &lt;p&gt;Un vídeo de demostración de esta técnica que podéis ver en YouTube:&lt;/p&gt;&lt;embed src="http://www.youtube.com/v/6NcIJXTlugc" width="425" height="350" type="application/x-shockwave-flash" wmode="transparent"&gt;&lt;/embed&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=39296" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Procesamiento+de+im_26002300_225_3B00_genes/default.aspx">Procesamiento de im&amp;#225;genes</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Seam+Carving/default.aspx">Seam Carving</category></item><item><title>¿Es rentable una migración desde cero?</title><link>http://geeks.ms/blogs/aruiz/archive/2007/10/02/191-es-rentable-una-migraci-243-n-desde-cero.aspx</link><pubDate>Tue, 02 Oct 2007 14:33:17 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:38992</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=38992</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=38992</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/10/02/191-es-rentable-una-migraci-243-n-desde-cero.aspx#comments</comments><description>&lt;p&gt;Uno de los impulsos más difíciles de reprimir para un programador es el de ver un código antiguo, de esos que los años han ido degradando, y no caer en la tentación de rehacer esa funcionalidad que se nota que tiene ñapa sobre ñapa, que se hace de manera ineficiente, que tiene cincuenta mil ifs anidados...&lt;/p&gt; &lt;p&gt;Por otra parte, cada cierto tiempo, las empresas se plantean realizar migraciones de aplicaciones antiguas a una tecnología más nueva. Los motivos esgrimidos suelen ser aprovechar una infraestructura que ha ido mejorando con el paso del tiempo, que puede soportar un mayor número de usuarios, o mayor carga de trabajo. &lt;/p&gt; &lt;p&gt;Sin embargo, el software de dichas empresas puede no haber crecido a la par, por ejemplo&amp;nbsp;porque cuando se desarrolló la aplicación no había esas necesidades, y no se incluyeron como requisitos no funcionales.&lt;/p&gt; &lt;p&gt;Ese es el momento en el que, armados con todas las herramientas estupendas que tenemos a día de hoy, te encuentras con la &amp;quot;fácil&amp;quot; tarea de realizar la migración. Y ya que estamos, como hacer esa migración es &amp;quot;tan sencillo&amp;quot;, pues ya &lt;em&gt;aprovechamos y tenemos que incluir cierta funcionalidad que no tenía la aplicación original&lt;/em&gt;. Como todos sabemos, una migración es algo que &amp;quot;no produce valor añadido&amp;quot; - dicen - y claro, puede tener un cierto coste que, elevado o no, hay que justificar. Y de ahí el hecho de meterle &amp;quot;algo nuevo&amp;quot;.&lt;/p&gt; &lt;p&gt;¿Quién no se ha encontrado con una situación así?&lt;/p&gt; &lt;p&gt;Tras realizar la migración, el resultado habitual, y que sorprende a muchos clientes, es el siguiente:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;La aplicación migrada suele&amp;nbsp;tener más bugs que la original&lt;/strong&gt;. Normalmente suele ser porque ese código tan feo suele cubrir los cincuenta millones de casos especiales que se presentan durante el proceso que cubre, y al que nadie hace caso en el momento de plantear la nueva solución. Generalmente, no es posible bajar al nivel del código para todo el sistema antiguo cuando se diseña el nuevo.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;El rendimiento de la nueva aplicación suele ser menor&lt;/strong&gt;. Esto pasa más a menudo de lo que pudiera parecer, por ejemplo&amp;nbsp;cuando se migra una aplicación en entorno host (cobol) a tecnologías actuales (Java - .NET). Cierto, la tecnología moderna te proporciona mucha más funcionalidad de base, pero a un cierto precio. &lt;em&gt;Acelera el desarrollo, pero no necesariamente el rendimiento&lt;/em&gt;.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;De ahí que surja la pregunta: ¿realmente es rentable hacer una migración de una aplicación desde cero?&lt;/p&gt; &lt;p&gt;Mi opinión es que depende. Hay situaciones en las que puede interesar migrar. Pero en la mayoría de los casos, puede ser interesante pensar en la reutilización de ese sistema, por ejemplo aplicando una arquitectura orientada a servicios. La nueva funcionalidad se puede desarrollar con otra tecnología más actual, y ciertas partes del sistema antiguo se pueden ir migrando paulatinamente.&lt;/p&gt; &lt;p&gt;Y vosotros, ¿qué opináis?&lt;/p&gt; &lt;p&gt;P.D.: Al hilo, &lt;a href="http://www.joelonsoftware.com/articles/fog0000000069.html" target="_blank"&gt;un artículo&lt;/a&gt;&amp;nbsp;muy interesante.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=38992" width="1" height="1"&gt;</description></item><item><title>Publicando aplicaciones ClickOnce en web (sin IIS)</title><link>http://geeks.ms/blogs/aruiz/archive/2007/09/25/publicando-aplicaciones-clickonce-en-web-sin-iis.aspx</link><pubDate>Tue, 25 Sep 2007 08:30:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:37197</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=37197</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=37197</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/09/25/publicando-aplicaciones-clickonce-en-web-sin-iis.aspx#comments</comments><description>&lt;p&gt;Bueno, bueno, bueno...&lt;/p&gt;
&lt;p&gt;En un proyecto en el que se querían ahorrar &lt;strike&gt;unas pelillas&lt;/strike&gt; unos eurillos (esa cabeza...) en licencias (y gastarse &lt;strike&gt;muchas&lt;/strike&gt; muchos más en gente de sistemas, supongo...) me pidieron evaluar la posibilidad de crear una aplicación que se pudiese actualizar automáticamente, de forma sencilla. Por mi deformación profesional, mi cabeza pensó directamente en ClickOnce. Claro, si publicar con ClickOnce está chupado, y cada vez que se publica una nueva versión, la aplicación se puede actualizar automáticamente! (depende de cómo lo configures, claro...).&lt;/p&gt;
&lt;p&gt;Pero luego me dí cuenta de un pequeño problema. Para poder tener esa aplicación disponible necesito un IIS para que las aplicaciones puedan comprobar si hay una nueva versión... O no?&lt;/p&gt;
&lt;p&gt;Pues no.&lt;/p&gt;
&lt;p&gt;Empecé a pensar un poco sobre cómo debería funcionar ClickOnce. El cliente se descarga un fichero .application desde una URL, que no es más que un fichero XML firmado que le indica, entre otras cosas, qué manifiesto de aplicación es el que tiene que procesar para obtener los ficheros de la aplicación actual. Así que pide al servidor web dicho fichero (un .manifest). Este fichero vuelve a ser un XML firmado donde aparecen una lista de ficheros etiquetados, con el hash de cada fichero.&lt;/p&gt;
&lt;p&gt;Para cada fichero, el cliente comprueba si ya tiene el fichero (en el caso en el que se haya instalado otra versión previamente). Si lo tiene&amp;nbsp;calcula el hash del fichero en local, y si coincide con el que le indica el manifiesto, no se lo descarga. Si difiere o no lo tiene, le pide el fichero al servidor, lo descarga, calcula el hash del fichero, y si coincide con el que indica el manifiesto continua con el proceso (y si no coincide, no deja continuar la instalación). Por lo tanto... ¿cuál es el papel del servidor en todo este trajín? No es más que un repositorio de ficheros. El cliente es el que realmente realiza todo el trabajo y le va pidiendo los ficheros que necesita para instalar o actualizar la aplicación.&lt;/p&gt;
&lt;p&gt;Por lo tanto... Esto debería funcionar con cualquier otro servidor web... ¿O no?. Decidí hacer una prueba rápida con un Apache. Coloqué los resultados de una publicación en un directorio virtual, y abriendo un Internet Explorer le indiqué la URL del fichero .application. Y claro, no funcionó. No funcionó porque el Apache no tenía los tipos mime configurados correctamente. Es decir, para que el Internet Explorer sepa cómo tiene que procesar el fichero .application, es necesario que el servidor web le indique de qué tipo es el fichero que le está enviando. Es como cuando queremos volcar un PDF directamente por el stream de salida del objeto response, que tenemos que poner las cabeceras apropiadas.&lt;/p&gt;
&lt;p&gt;Así que, creamos un fichero de texto con el nombre .htaccess, que contenga las siguientes líneas:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;AddType application/x-ms-application application&lt;br /&gt;&lt;code&gt;AddType application/x-ms-manifest manifest&lt;/code&gt;&lt;/font&gt;&lt;br /&gt;&lt;code&gt;AddType application/octet-stream deploy&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Y listo! Funciona de maravilla!&lt;/p&gt;
&lt;p&gt;Por cierto... Sobre cómo solucionar problemas de ClickOnce, podéis ver más información &lt;a class="" href="http://msdn2.microsoft.com/en-us/library/ms228998.aspx" target="_blank"&gt;aquí&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Saludos!&lt;/p&gt;
&lt;p&gt;P.D.: Muchas gracias a &lt;a class="" title="La web de Daniel Celemín (Lord Fred)" href="http://www.geocities.com/dcelemin/" target="_blank"&gt;Daniel Celemín&lt;/a&gt; (&lt;a class="" href="http://cezgs.computeremuzone.com/eng/card.php?id=8" target="_blank"&gt;Lord Fred&lt;/a&gt;) por la estupenda caricatura :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=37197" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/ClickOnce/default.aspx">ClickOnce</category></item><item><title>ISV Tour - Madrid</title><link>http://geeks.ms/blogs/aruiz/archive/2007/06/21/isv-tour-madrid.aspx</link><pubDate>Thu, 21 Jun 2007 08:23:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:16392</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=16392</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=16392</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/06/21/isv-tour-madrid.aspx#comments</comments><description>&lt;p&gt;Muy buenas!&lt;/p&gt;
&lt;p&gt;Hace mucho, mucho tiempo, en una galaxia muy lejana... Esto... Bueno, que hace demasiado tiempo desde mi último post. Demasiados cambios y muy poco tiempo para contarlos. Pero vamos a lo que vamos...&lt;/p&gt;
&lt;p&gt;Ayer tuve el placer de asistir al Innovation Days en Madrid, donde &lt;a href="http://blogs.msdn.com/josemurl/"&gt;José Murillo&lt;/a&gt;, Isabel Gómez, &lt;a href="http://blogs.msdn.com/cesardelatorre/default.aspx"&gt;César de la Torre&lt;/a&gt;, Daniel López, &lt;a class="" href="http://geeks.ms/blogs/maramos/"&gt;Miguel Ángel Ramos&lt;/a&gt; (en sustitución de &lt;a href="http://www.byteabyte.net/"&gt;Alejandro Mezcua&lt;/a&gt;) y &lt;a href="http://geeks.ms/blogs/unai/"&gt;Unai Zorrilla&lt;/a&gt; nos estuvieron mostrando las novedades que vamos a poder disfrutar en breve, (bien sea con Longhorn, Orcas o Silverlight), además de poder ver un poco de ASP.NET AJAX y una interesante charla sobre SaaS.&lt;/p&gt;
&lt;p&gt;Las charlas, como siempre, me dejaron con ganas de más. Y es que sólo un día para tratar sobre todos estos temas es demasiado poco... Pero en fin, que te despiertan el gusanillo para cacharrear.&lt;/p&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=16392" width="1" height="1"&gt;</description></item><item><title>Entrada rápida...</title><link>http://geeks.ms/blogs/aruiz/archive/2007/04/09/entrada-r-pida.aspx</link><pubDate>Mon, 09 Apr 2007 07:55:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:12892</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=12892</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=12892</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/04/09/entrada-r-pida.aspx#comments</comments><description>&lt;p&gt;¡Hola a todos!&lt;/p&gt;&lt;p&gt;&amp;nbsp;Estoy en proceso de mudanza. Me he cambiado de casa (aún de alquiler, pero todo llegará...) y en la casa nueva no tengo internet, con lo que me es difícil hacer las cosas habituales (es decir, actualizar este blog y el de &lt;a href="http://historiasdeunconsultor.blogspot.com/" target="_blank"&gt;historias de un consultor&lt;/a&gt;).&lt;br&gt;&lt;br&gt;Aun así, estoy aprovechando un poco el tiempo leyéndome el libro &lt;a href="http://www.amazon.com/CLR-via-Second-Pro-Developer/dp/0735621632/ref=pd_bbs_sr_1/103-8531770-2410262?ie=UTF8&amp;amp;s=books&amp;amp;qid=1176105731&amp;amp;sr=1-1" target="_blank"&gt;CLR via C#&lt;/a&gt;, que me ha llegado de Amazon hace bien poquito, junto con otro libro menos conocido, el &lt;a href="http://www.amazon.com/Programming-Challenges-Steven-S-Skiena/dp/0387001638" target="_blank"&gt;Programming Challenges&lt;/a&gt; de Steven S. Skiena y Miguel A. Revilla. Muy recomendable para repasar conceptos de estructuras de datos, y aprender a pensar un poco más al estilo de Programancia101.&lt;/p&gt;&lt;p&gt;Aprovechad ahora los que estéis en zona Euro, que como el Euro está fuerte, los libros en Amazon salen tirados!!! (los dos por poco más de 60€)&amp;nbsp;&lt;/p&gt;&lt;p&gt;Saludos!!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=12892" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Libros/default.aspx">Libros</category></item><item><title>Desarrollo de aplicaciones ASP.NET 2.0 en tres capas</title><link>http://geeks.ms/blogs/aruiz/archive/2007/03/07/desarrollo-de-aplicaciones-asp-net-2-0-en-tres-capas.aspx</link><pubDate>Wed, 07 Mar 2007 12:45:05 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:11413</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=11413</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=11413</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/03/07/desarrollo-de-aplicaciones-asp-net-2-0-en-tres-capas.aspx#comments</comments><description>&lt;p&gt;Bajo la apariencia de &lt;a href="http://msdn2.microsoft.com/en-us/library/aa581769.aspx"&gt;una página muy sencillita&lt;/a&gt;, en el MSDN tenemos disponible una serie de&amp;nbsp;tutoriales bastante completos sobre cómo realizar aplicaciones en tres capas utilizando ASP.NET 2.0.&lt;/p&gt; &lt;p&gt;Elige tu sabor favorito (C# o VB.NET), y prepárate para aprender en&amp;nbsp;17 tutoriales cómo organizar una aplicación como dios manda.&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=11413" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>¡Me lo estoy pasando pipa en casa! (con C# 2005 Express)</title><link>http://geeks.ms/blogs/aruiz/archive/2007/03/02/me-lo-estoy-pasando-pipa-en-casa-con-c-2005-express.aspx</link><pubDate>Fri, 02 Mar 2007 11:06:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:11216</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=11216</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=11216</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/03/02/me-lo-estoy-pasando-pipa-en-casa-con-c-2005-express.aspx#comments</comments><description>&lt;P&gt;Hola a todos,&lt;/P&gt;
&lt;P&gt;Sigo con mis proyectos en casa, para el desarrollo de un juego (y de varias herramientas). En &lt;A href="http://cezgs.computeremuzone.com/" target=_blank&gt;http://cezgs.computeremuzone.com/&lt;/A&gt; estamos desarrollando cositas (top secret hasta que se publiquen, sorry), y alguna vez desarrollo alguna herramienta interna.&lt;/P&gt;
&lt;P&gt;Ahora mismo estoy enfrascado con un tracker que permita componer melodías para ordenadores de 8 bits. De momento está enfocado al chip AY que traían los CPC (todos) y Spectrum de 128kb.&lt;/P&gt;
&lt;P&gt;Así que buscando por la red, encontré &lt;A href="http://sashnov.nm.ru/libayemu.html" target=_blank&gt;una librería&lt;/A&gt; que emulaba el comportamiento de dicho chip, escrita en C. En Windows no compilaba (hasta que añadí un #define en un fichero .h), y cuando lo tuve funcionando, la migré a C#.&lt;/P&gt;
&lt;P&gt;La verdad es que mientras la migraba me sorprendí de lo sencillo que era. Y&amp;nbsp;podéis descargar&amp;nbsp;el código fuente de dicho emulador, en C#, &lt;A href="http://augusto.ruiz.googlepages.com/LibAyEmu_.rar" target=_blank&gt;haciendo click aquí&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Saludos!&lt;/P&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=11216" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/.NET/default.aspx">.NET</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Retro/default.aspx">Retro</category></item><item><title>Mis experiencias con Visual C++ 2005 Express</title><link>http://geeks.ms/blogs/aruiz/archive/2007/02/13/mis-experiencias-con-visual-c-2005-express.aspx</link><pubDate>Tue, 13 Feb 2007 10:52:54 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:10336</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=10336</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=10336</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/02/13/mis-experiencias-con-visual-c-2005-express.aspx#comments</comments><description>&lt;p&gt;Hola a todos!&lt;/p&gt; &lt;p&gt;Desde hace bastante tiempo estoy desarrollando un juego en PC usando C++ y OpenGL. (¡No, no me tiréis piedras, no usar DirectX tiene una explicación!). Así que este fin de semana, después de desesperarme con el Dev-CPP, decidí cambiarme y usar el Visual C++ 2005 Express.&lt;/p&gt; &lt;p&gt;La razón de no usar DirectX es que para &lt;strike&gt;dominar el mundo&lt;/strike&gt; conseguir la mayor distribución posible necesito que el juego sea multiplataforma. De ahí que use OpenGL, SDL y C++. :P&lt;/p&gt; &lt;p&gt;Ya tenía experiencia con el Visual C++ 6 y con el Visual C++ 2003, así que sabía que lo que me iba a encontrar era conocido, y probablemente podría aumentar mi productividad.&lt;/p&gt; &lt;p&gt;También tenía algunas dudas sobre si hacer el cambio o no, sobre todo después de leer los posts de &lt;a href="http://geeks.ms/blogs/rfog/default.aspx"&gt;Rafael Ontivero&lt;/a&gt;, pero como este proyecto es propio, consideré que no corría riesgos por probarlo.&lt;/p&gt; &lt;p&gt;A la hora de configurar el entorno de desarrollo, todo ha ido como la seda. Directorios para includes, librerías, etc... Estupendamente. Terreno conocido. :)&lt;/p&gt; &lt;p&gt;Hay un par de cosas que no me han gustado de esta versión:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A la hora de compilar, siempre genera la versión Release.&lt;/li&gt; &lt;li&gt;Cuando pulsas F5, siempre genera la versión Debug.&lt;/li&gt; &lt;li&gt;No he visto forma humana de hacer refactoring.&lt;/li&gt; &lt;li&gt;El Intellisense funciona &lt;em&gt;cuando quiere&lt;/em&gt;, y sólo sobre lo que hubiese ya compilado al cargar el proyecto. Posteriores compilaciones añadiendo métodos, propiedades, etc, etc, no hacen que se refresque el Intellisense (o eso me ha parecido).&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Si lo pienso fríamente, tiene sentido. Pero no me deja elegir. El combo para elegir la configuración de generación de assemblies está deshabilitado, y la verdad es que no se si está capado para la versión Express (en cuyo caso, sería mejor que no apareciese en absoluto) o que soy un zote y no he encontrado aún la forma de habilitarlo (esto será lo más probable...)&lt;/p&gt; &lt;p&gt;En cuanto al rendimiento de la aplicación, no he notado mejora alguna, pero tampoco pérdida alguna... Teniendo en cuenta que el trabajo duro lo hace OpenGL, es lo razonable ;)&lt;/p&gt; &lt;p&gt;Pero claro, el poder disponer de una herramienta como ésta, y gratuita, es&amp;nbsp;algo muy, muy interesante. A aquellos frikis como yo que quieran usar C++ para proyectos personales, se lo recomiendo encarecidamente. Pero sólo en el caso de que sean aplicaciones no .NET, ya que la productividad de C# sigue estando a años luz que la de C++ (al menos para mí).&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=10336" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Opini_26002300_243_3B00_n/default.aspx">Opini&amp;#243;n</category></item><item><title>Cómo evitar la limitación de anchura en los formularios Windows (o poner la tuya propia)</title><link>http://geeks.ms/blogs/aruiz/archive/2007/02/07/c-mo-evitar-la-limitaci-n-de-anchura-en-los-formularios-windows-o-poner-la-tuya-propia.aspx</link><pubDate>Wed, 07 Feb 2007 11:36:53 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:9979</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=9979</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=9979</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/02/07/c-mo-evitar-la-limitaci-n-de-anchura-en-los-formularios-windows-o-poner-la-tuya-propia.aspx#comments</comments><description>&lt;p&gt;En el &lt;a href="http://blog.metaemotion.com/"&gt;blog de Metaemotion&lt;/a&gt; hay &lt;a href="http://blog.metaemotion.com/2007/02/06/como-evitar-la-limitacion-de-los-112px-de-anchura-en-formularios-para-windows/"&gt;un artículo interesante&lt;/a&gt; (en castellano) en el que se detalla cómo se puede eliminar la restricción de tamaño mínimo que tienen impuestas por defecto las ventanas de Windows.&lt;/p&gt; &lt;p&gt;Lo que no se comenta en ese artículo es que podemos aprovechar esa misma técnica para cambiar la restricción de tamaño mínimo cuando esta esté entre 0 y 112 píxeles (para el resto de tamaños se puede usar la propiedad MinimumSize de la clase System.Windows.Forms.Form).&lt;/p&gt; &lt;p&gt;La lectura es más que recomendable ;)&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=9979" width="1" height="1"&gt;</description></item><item><title>Creando un sistema de reglas sencillo, pero flexible (IA)</title><link>http://geeks.ms/blogs/aruiz/archive/2007/02/06/creando-un-sistema-de-reglas-sencillo-pero-flexible-ia.aspx</link><pubDate>Tue, 06 Feb 2007 14:43:37 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:9916</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=9916</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=9916</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/02/06/creando-un-sistema-de-reglas-sencillo-pero-flexible-ia.aspx#comments</comments><description>&lt;p&gt;Hola!&lt;/p&gt; &lt;p&gt;Curioseando un poco por la red, he encontrado &lt;a href="http://www.flipcode.dxbug.com/articles/Creating_Real_Artificial_Intelligence/"&gt;un artículo&lt;/a&gt; muy interesante en &lt;a href="http://www.flipcode.dxbug.com/"&gt;#flipcode&lt;/a&gt;, en el que el autor comenta cómo se puede crear un sistema de reglas utilizando .NET que tome decisiones basándose en una máquina de estados.&lt;/p&gt; &lt;p&gt;Realmente esto no es novedoso, pero me ha llamado la atención el sistema tan sencillo que ha creado el autor para componer reglas básicas (lo que en el artículo llama primitivas).&lt;/p&gt; &lt;p&gt;Así que si tenéis que hacer una máquina de estados, os recomiendo que lo peguéis una ojeada.&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt; &lt;p&gt;UPDATE: Obviamente, esto no os será interesante si estáis utilizando Workflow Foundation... Pero por desgracia no todo el mundo puede usar .NET 3.0 ;)&lt;/p&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=9916" width="1" height="1"&gt;</description></item><item><title>Invocando páginas ASP.NET con procesos pesados y no morir en el intento (y II)</title><link>http://geeks.ms/blogs/aruiz/archive/2007/02/02/invocando-p-ginas-asp-net-con-procesos-pesados-y-no-morir-en-el-intento-y-ii.aspx</link><pubDate>Fri, 02 Feb 2007 14:00:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:9664</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=9664</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=9664</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/02/02/invocando-p-ginas-asp-net-con-procesos-pesados-y-no-morir-en-el-intento-y-ii.aspx#comments</comments><description>&lt;p&gt;&lt;a class="" href="http://geeks.ms/blogs/aruiz/archive/2007/01/31/invocando-p-ginas-asp-net-con-procesos-pesados-y-no-morir-en-el-intento.aspx#9652" target="_blank"&gt;A petición de espinete&lt;/a&gt; escribo una segunda parte del artículo, en el que adjunto el código fuente de ejemplo con lo que se proponía en &lt;a class="" href="http://geeks.ms/blogs/aruiz/archive/2007/01/31/invocando-p-ginas-asp-net-con-procesos-pesados-y-no-morir-en-el-intento.aspx" target="_blank"&gt;el artículo anterior&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href="http://geeks.ms/blogs/aruiz/SampleSrc/Geeks.ProcesamientoPesado.zip" target="_blank"&gt;En el código adjunto&lt;/a&gt; se pueden ver las siguientes clases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Trabajador: Esta clase es la que tiene implementado el proceso pesado. En nuestro caso, simplemente irá desde un número especificado como mínimo hasta el máximo, esperando un segundo en cada iteración.  &lt;li&gt;GestionTrabajadores: Esta clase es el singleton al que se refiere el artículo anterior. Se encarga de gestionar una tabla hash en la que las instancias de la clase Trabajador se identifican mediante un Guid.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Además, podemos ver que hay tres páginas en el proyecto Web:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Inicial.aspx: En esta página se crea una instancia de la clase Trabajador, se la inicializa, y se la añade a la clase GestionTrabajadores, tras haber creado un Guid para identificarla. Posteriormente se reenvía al usuario a la siguiente página, pasando el Guid de la petición actual.  &lt;li&gt;EnProceso.aspx: En esta página se muestra el progreso de la petición actual. Si se detecta que la petición ha finalizado, se reenvía al usuario a la siguiente página.  &lt;li&gt;Terminado.aspx: En esta página simplemente se muestra un mensaje que indica que el procesamiento ha finalizado.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Obviamente, las mejoras que se le pueden hacer a este ejemplo son innumerables, pero aquí dejo un par de&amp;nbsp;ideas, a ver si alguien se anima y las realiza, aportándolas para la comunidad:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;La página Inicial.aspx, en vez de notificar el GUID de la petición, podría enviarnos a la página EnProceso.aspx, y en esta página que se muestren los diferentes trabajos que hay en curso. Para ello bastaría con proporcionar un enumerador a la clase GestionTrabajadores para recorrer la tabla hash.  &lt;li&gt;La página EnProceso.aspx podría utilizar AJAX para no tener que refrescarse cada dos segundos.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Bueno, pues esto es todo por hoy.&lt;/p&gt; &lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=9664" width="1" height="1"&gt;</description><enclosure url="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.96.64/ProcesamientoPesado.zip" length="25972" type="application/x-zip-compressed" /></item><item><title>Gadget de Windows Vista: Daily Dilbert</title><link>http://geeks.ms/blogs/aruiz/archive/2007/02/01/gadget-de-windows-vista-daily-dilbert.aspx</link><pubDate>Thu, 01 Feb 2007 18:24:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:9618</guid><dc:creator>Augusto Ruiz</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/rsscomments.aspx?PostID=9618</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/aruiz/commentapi.aspx?PostID=9618</wfw:comment><comments>http://geeks.ms/blogs/aruiz/archive/2007/02/01/gadget-de-windows-vista-daily-dilbert.aspx#comments</comments><description>&lt;P&gt;Hola!&lt;/P&gt;
&lt;P&gt;En &lt;A class="" href="http://www.codeproject.com/" target=_blank&gt;CodeProject&lt;/A&gt; tenéis disponible un ejemplo de cómo crear un gadget para Windows Vista. Este gadget muestra la tira de Dilbert, y nos permite mostrar las tiras anteriores.&lt;/P&gt;
&lt;P&gt;El artículo lo podéis leer &lt;A class="" href="http://www.codeproject.com/useritems/DailyDilbert.asp" target=_blank&gt;aquí&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Saludos!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=9618" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Gadgets/default.aspx">Gadgets</category><category domain="http://geeks.ms/blogs/aruiz/archive/tags/Windows+Vista/default.aspx">Windows Vista</category></item></channel></rss>