tag:blogger.com,1999:blog-86995771648780046692024-02-20T12:55:53.167-08:00Thepirat blog<br>de Federico Colombo.<br>
Consejos informáticos .NET, VB, C#, Windows, etc...Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.comBlogger25125tag:blogger.com,1999:blog-8699577164878004669.post-81936380289469643652013-02-21T07:42:00.001-08:002013-02-21T08:04:57.045-08:00ISO/IEC 25010:2011 - Characteristics summaryThe international standard <strong>ISO/IEC 25010</strong> (ISO/IEC 9126) defines two quality models that provides a consistent terminology for specifying, measuring and evaluating system and software product quality:<br />
<ul>
<li>A <strong>quality in use</strong> <strong>model</strong> composed of five characteristics that relate to the outcome of interaction when a product is used in a particular context of use.</li>
<li>A <strong>product quality model</strong> composed of eight characteristics that relate to static properties of software and dynamic properties of the computer system.</li>
</ul>
<div style="text-align: center;">
<span style="color: orange; font-size: large;">Quality in use model</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtubUCuSentoPhV66p3CKR46kiARIeSHDpNHHGgVAJFm2HQXhNmXxvXMk-9DC2VRxcUmyK32h9SmXSWLv3JzPGXLtuSKvpI5IX9jSd52fr9y2cpHeLORE0zq4yKF4dXiAA1WpfSEBQFg3A/s1600/qin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtubUCuSentoPhV66p3CKR46kiARIeSHDpNHHGgVAJFm2HQXhNmXxvXMk-9DC2VRxcUmyK32h9SmXSWLv3JzPGXLtuSKvpI5IX9jSd52fr9y2cpHeLORE0zq4yKF4dXiAA1WpfSEBQFg3A/s640/qin.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<em><span style="color: orange;">Quality in use characteristics and subcharacteristics</span></em></div>
<ul>
<li><span style="font-family: inherit;"><strong>Effectiveness</strong>: accuracy and completeness with which users achieve specified goals.</span></li>
<li><span style="font-family: inherit;"><strong>Efficiency</strong>: resources expended in relation to the accuracy and completeness with which users achieve goals.</span></li>
<li><span style="font-family: inherit;"><strong>Satisfaction</strong>: degree to which user needs are satisfied when a system is used in a specified context of use.</span></li>
<ul>
<li><span style="font-family: inherit;"><em>Usefulness</em>: user is satisfied with their perceived achievement of pragmatic goals.</span></li>
<li><span style="font-family: inherit;"><em>Trust</em>: stakeholders has confidence that a product or system will behave as intended.</span></li>
<li><span style="font-family: inherit;"><em>Pleasure</em>: user obtains pleasure from fulfilling their personal needs.</span></li>
<li><span style="font-family: inherit;"><em>Comfort</em>: user is satisfied with physical comfort.</span></li>
</ul>
<li><span style="font-family: inherit;"><strong>Freedom from risk</strong>: degree to which a system mitigates the risk to economic status, human life, health, or the environment.</span></li>
<ul>
<li><span style="font-family: inherit;"><em>Economic risk mitigation</em>: system mitigates the potential risk to financial status in the intended contexts of use. </span></li>
<li><span style="font-family: inherit;"><em>Health and safety risk mitigation</em>: system mitigates the potential risk to people in the intended contexts of use.</span></li>
<li><span style="font-family: inherit;"><em>Environmental risk mitigation</em>: system mitigates the potential risk to property or the environment in the intended contexts of use.</span></li>
</ul>
<li><span style="font-family: inherit;"><strong>Context coverage</strong>: degree to which a system can be used with effectiveness, efficiency, freedom from risk and satisfaction in specified contexts of use and in contexts beyond those initially explicitly identified.</span></li>
<ul>
<li><span style="font-family: inherit;"><em>Context completeness</em>: system can be used in all the specified contexts of use.</span></li>
<li><span style="font-family: inherit;"><em>Flexibility</em>: system can be used in contexts beyond those initially specified in the requirements</span></li>
</ul>
</ul>
<div>
<br /></div>
<div style="text-align: center;">
<span style="color: orange; font-size: large;">Product quality model</span><br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfZ3mEAmLySIUnQTgRBT_NYPp1FbTIsxLyz2O6AZGRaN_08Lo7PsM0PCpHA2v5-rGbytXuTqGMAVhirzTGo_XDBuS1D0O1BvwCtYUcQYCAkRPqRdpB5mrRqVcZmREn-SZZ_RYjhzVIpVM5/s1600/pq.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfZ3mEAmLySIUnQTgRBT_NYPp1FbTIsxLyz2O6AZGRaN_08Lo7PsM0PCpHA2v5-rGbytXuTqGMAVhirzTGo_XDBuS1D0O1BvwCtYUcQYCAkRPqRdpB5mrRqVcZmREn-SZZ_RYjhzVIpVM5/s640/pq.jpg" width="640" /></a></div>
<div style="text-align: center;">
<i><span style="color: orange;">Product quality characteristics and subcharacteristics</span></i></div>
<br />
<ul>
<li><span style="font-family: inherit;"><b>Functional suitability</b>: degree to which a system provides functions that meet stated needs when used under specified conditions.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Functional completeness</i>: degree to which the set of functions covers all the specified tasks and user objectives.</span></li>
<li><span style="font-family: inherit;"><i>Functional correctness</i>: system provides the correct results with the needed degree of precision.</span></li>
<li><span style="font-family: inherit;"><i>Functional appropriateness</i>: the functions facilitate the accomplishment of specified tasks and objectives.</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Performance efficiency</b>: performance relative to the amount of resources used under stated conditions.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Time behaviour</i>: response, processing times and throughput rates of a system, when performing its functions, meet requirements.</span></li>
<li><span style="font-family: inherit;"><i>Resource utilization</i>: the amounts and types of resources used by a system, when performing its functions, meet requirements.</span></li>
<li><span style="font-family: inherit;"><i>Capacity</i>: the maximum limits of a product or system parameter meet requirements.</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Compatibility</b>: degree to which a system can exchange information with systems, and/or perform its required functions, while sharing the same hardware or software environment.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Co-existence</i>: product can perform its functions efficiently while sharing environment and resources with other products.</span></li>
<li><span style="font-family: inherit;"><i>Interoperability</i>: a system can exchange information with other systems and use the information that has been exchanged.</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Usability</b>: degree to which a system can be used with effectiveness, efficiency and satisfaction in a specified context of use.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Appropriateness recognizability</i>: users can recognize whether a system is appropriate for their needs, even before it is implemented.</span></li>
<li><span style="font-family: inherit;"><i>Learnability</i>: system can be used to achieve specified goals of learning to use the system.</span></li>
<li><span style="font-family: inherit;"><i>Operability</i>: system has attributes that make it easy to operate and control.</span></li>
<li><span style="font-family: inherit;"><i>User error protection</i>: system protects users against making errors.</span></li>
<li><span style="font-family: inherit;"><i>User interface aesthetics</i>: user interface enables pleasing and satisfying interaction for the user.</span></li>
<li><span style="font-family: inherit;"><i>Accessibility</i>: system can be used by people with the widest range of characteristics and capabilities.</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Reliability</b>: degree to which a system performs specified functions under specified conditions for a specified period of time.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Maturity</i>: system meets needs for reliability under normal operation.</span></li>
<li><span style="font-family: inherit;"><i>Availability</i>: system is operational and accessible when required for use.</span></li>
<li><span style="font-family: inherit;"><i>Fault tolerance</i>: system operates as intended despite the presence of hardware or software faults.</span></li>
<li><span style="font-family: inherit;"><i>Recoverability</i>: system can recover data affected and re-establish the desired state of the system is case of an interruption or a failure.</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Security</b>: degree to which a system protects information and data so that persons or other products or systems have the degree of data access appropriate to their types and levels of authorization.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Confidentiality</i>: system ensures that data are accessible only to those authorized to have access.</span></li>
<li><span style="font-family: inherit;"><i>Integrity</i>: system prevents unauthorized access to, or modification of, computer programs or data.</span></li>
<li><span style="font-family: inherit;"><i>Non-repudiation</i>: actions or events can be proven to have taken place, so that the events or actions cannot be repudiated later.</span></li>
<li><span style="font-family: inherit;"><i>Accountability</i>: actions of an entity can be traced uniquely to the entity.</span></li>
<li><span style="font-family: inherit;"><i>Authenticity</i>: the identity of a subject or resource can be proved to be the one claimed.</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Maintainability</b>: degree of effectiveness and efficiency with which a system can be modified by the intended maintainers.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Modularity</i>: system is composed of components such that a change to one component has minimal impact on other components.</span></li>
<li><span style="font-family: inherit;"><i>Reusability</i>: an asset can be used in more than one system, or in building other assets.</span></li>
<li><span style="font-family: inherit;"><i>Analysability</i>: effectiveness and efficiency with which it is possible to assess the impact of an intended change.</span></li>
<li><span style="font-family: inherit;"><i>Modifiability</i>: system can be effectively and efficiently modified without introducing defects or degrading existing product quality.</span></li>
<li><span style="font-family: inherit;"><i>Testability</i>: effectiveness and efficiency with which test criteria can be established for a system.</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Portability</b>: degree of effectiveness and efficiency with which a system can be transferred from one hardware, software or other operational or usage environment to another.</span></li>
<ul>
<li><span style="font-family: inherit;"><i>Adaptability</i>: system can effectively and efficiently be adapted for different or evolving hardware, software or usage environments.</span></li>
<li><span style="font-family: inherit;"><i>Installability</i>: effectiveness and efficiency with which a system can be successfully installed and/or uninstalled.</span></li>
<li><span style="font-family: inherit;"><i>Replaceability</i>: product can be replaced by another specified software product for the same purpose in the same environment.</span></li>
</ul>
</ul>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-39306376778326077652012-08-06T12:30:00.001-07:002012-08-06T12:30:33.233-07:00Localización (traducción) con Entity Framework<a href="http://www.codeproject.com/Tips/369845/Localization-with-Entity-Framework">Aquí</a> comparto una forma para localizar (o traducir) entidades de una base de datos SQL mediante Entity Framework.<br />
<br />
<br />
Me he topado con el problema de la traducción a diferentes idiomas de los datos de base de datos SQL para aplicaciones que utilizan .NET Entity Framework.<br />
<br />
Aquí, se propone una solución simple que consiste en unos pocos cambios a una base de datos existente (nuevas tablas de traducción, sin modificación de las tablas existentes), y un método para traducir automáticamente entidades de datos mapeadas con Entity Framework.<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.codeproject.com/Tips/369845/Localization-with-Entity-Framework"><img border="0" height="316" src="http://i1039.photobucket.com/albums/a480/thepirat000/TranslateEF.png" width="640" /></a></div>
<div style="text-align: center;">
<a href="http://www.codeproject.com/Tips/369845/Localization-with-Entity-Framework"><span style="font-size: x-small;">http://www.codeproject.com/Tips/369845/Localization-with-Entity-Framework</span></a>
</div>
<br />Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-52179495550708412232011-03-24T10:36:00.000-07:002011-04-08T21:57:41.290-07:00Juego de la vida en C#<div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">Aquí comparto un simulador de <a href="http://es.wikipedia.org/wiki/Juego_de_la_vida">juego de la vida</a> hecho en C# 4.0 (WinForms).</div> <br />
<strong>Características:</strong><br />
<br />
- Variables como Algoritmo, Edad máxima, Ocupación y Tamaño del universo son configurables.<br />
(Presionar F1 para ver la ayuda de las teclas rápidas para modificar estas variables).<br />
<br />
- Uso de <a href="http://msdn.microsoft.com/es-es/library/dd460688.aspx">PLinq</a> para aprovechar al máximo la capacidad de procesadores multinúcleo.<br />
<br />
- Uso de <a href="http://msdn.microsoft.com/es-es/library/5ey6h79d(v=VS.100).aspx">Bloqueo de bits</a> (LockBits) para agilizar el rendimiento de la manipulación de la imagen del universo.<br />
<br />
<strong>Capturas de algunos de los patrones que se pueden lograr:</strong> <br />
<br />
<br />
<br />
<div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUrEY57o4xfQZ9tUizGpcf6Xtco8HR_o8vVerO5I_gSQy6z9QApqOJelT6bmx5Y_VfuhSRsN0WWMeskyAqaI63yCv0i8BwwwHZK9ktWGxFPdn3TAYyMFYeMlwLOfJwEuDp52GhtkTmyvJU/s1600/jv1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUrEY57o4xfQZ9tUizGpcf6Xtco8HR_o8vVerO5I_gSQy6z9QApqOJelT6bmx5Y_VfuhSRsN0WWMeskyAqaI63yCv0i8BwwwHZK9ktWGxFPdn3TAYyMFYeMlwLOfJwEuDp52GhtkTmyvJU/s1600/jv1.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW353vDjE20a_LhjIe1M3KJD2IGXvQEeHLY8BRleHIIl5rEUWdn3V25wbn7jOpk5oDAWRRVx_0Qwp-3Vt2F-AimZtMQ1xcfm_k6IqJ4t6wk6FIz86fPAexgWm4tl1rJlkBjS2zzgb71sMa/s1600/jvi1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW353vDjE20a_LhjIe1M3KJD2IGXvQEeHLY8BRleHIIl5rEUWdn3V25wbn7jOpk5oDAWRRVx_0Qwp-3Vt2F-AimZtMQ1xcfm_k6IqJ4t6wk6FIz86fPAexgWm4tl1rJlkBjS2zzgb71sMa/s1600/jvi1.png" /></a></div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><br />
</div><div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"></div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHNE4lzQWmsymgwkHWt57E9tfKpNC3Bto5JddGpNah8XvbwsJHVvqII6r1W6HxLV00IOmPT3_J7T27F9QLtFo8E9A6Gv8W1Ze7vUUIpWNhyphenhyphenZFZiEapgOa0rq8yPdrAOLVE1V_93h3w23qO/s1600/jvi2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHNE4lzQWmsymgwkHWt57E9tfKpNC3Bto5JddGpNah8XvbwsJHVvqII6r1W6HxLV00IOmPT3_J7T27F9QLtFo8E9A6Gv8W1Ze7vUUIpWNhyphenhyphenZFZiEapgOa0rq8yPdrAOLVE1V_93h3w23qO/s1600/jvi2.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRJ-6o0s4WFmvcGzQ9acWYcAW2-wVq4r7qQM7F5WIpMXjOeQKkhoPgYWHXamE6W09NF77TgeL2qIqwAXXk_3Rc_-fPb6kfxSX1s2EXM7ql4O2TwvNjgZcH_Mm8Ke1f6FzuRahOxY16MpGz/s1600/jv4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRJ-6o0s4WFmvcGzQ9acWYcAW2-wVq4r7qQM7F5WIpMXjOeQKkhoPgYWHXamE6W09NF77TgeL2qIqwAXXk_3Rc_-fPb6kfxSX1s2EXM7ql4O2TwvNjgZcH_Mm8Ke1f6FzuRahOxY16MpGz/s1600/jv4.png" /></a></div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"></div></div><div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBFHVsBO2vx_nmPR4eTUMV0aCoJAmspMG1cmcXCpn7f9HwCZuAX2SS9xTiZE4A7LLpKbe5HywZsQe71_eqTsdsDXUsst47dKct9Z_v378CdINyei7Mvdf362Pm6WsDjgoutp83-NYaWyVl/s1600/jv5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBFHVsBO2vx_nmPR4eTUMV0aCoJAmspMG1cmcXCpn7f9HwCZuAX2SS9xTiZE4A7LLpKbe5HywZsQe71_eqTsdsDXUsst47dKct9Z_v378CdINyei7Mvdf362Pm6WsDjgoutp83-NYaWyVl/s1600/jv5.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEQQi2BovIf0T5pLBROXPYwBRoWD7HWNe1PC4dRC6QIxTuL6a_51-cmKRp48_YcwmloIbB8To4LxEhkZg6NFcmLKLILtateNsLvpos9jTxg-A0isbDjyXDhrzT51di6N1mAoQIv7ALe_BV/s1600/jv6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEQQi2BovIf0T5pLBROXPYwBRoWD7HWNe1PC4dRC6QIxTuL6a_51-cmKRp48_YcwmloIbB8To4LxEhkZg6NFcmLKLILtateNsLvpos9jTxg-A0isbDjyXDhrzT51di6N1mAoQIv7ALe_BV/s1600/jv6.png" /></a></div><div style="text-align: center;"><br />
</div><div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEr7FRLFOvIngBvmXfLXjtuLwcZbXIaQROsKCKQatDz0l4-nCLyI1rZT_eoD7-5ov44bGo1VlRIvyNPJJMBvblJCXjt7AXWwFd390PsVkNptICuZjIMAL2zGNOZ-bRTqXsNs8VEQwCqjbs/s1600/jv7.png" imageanchor="1" style="clear: left; cssfloat: right; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEr7FRLFOvIngBvmXfLXjtuLwcZbXIaQROsKCKQatDz0l4-nCLyI1rZT_eoD7-5ov44bGo1VlRIvyNPJJMBvblJCXjt7AXWwFd390PsVkNptICuZjIMAL2zGNOZ-bRTqXsNs8VEQwCqjbs/s1600/jv7.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8rYIGaFE6_pabb3XB_Y2joS6WOE5O7FDTz9Lv76ZP4A8EzlbC9yagC8O6D7FHruLdxpE5IPgtfQWr_sUyjmc0iukdnO1nPCFZSHwZI8vh_DelsDbF0PY-0dUaJjnTyUJH0YlSSkPTp99j/s1600/jjjv1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="291" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8rYIGaFE6_pabb3XB_Y2joS6WOE5O7FDTz9Lv76ZP4A8EzlbC9yagC8O6D7FHruLdxpE5IPgtfQWr_sUyjmc0iukdnO1nPCFZSHwZI8vh_DelsDbF0PY-0dUaJjnTyUJH0YlSSkPTp99j/s320/jjjv1.png" width="320" /></a></div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; text-align: center;"><br />
</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; text-align: left;">Presionar F1 para mostrar la ayuda en pantalla.</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; text-align: center;"><br />
</div><div style="text-align: center;">Algunos algoritmos interesantes que puedes probar (presionando la tecla A) son:</div><div style="text-align: center;"><br />
</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; text-align: center;"><table border="1" style="text-align: center;"><tbody>
<tr><th>Algoritmo</th><th>Descripcion</th></tr>
<tr><td>5678/35678</td><td>(caótico) diamantes, catástrofes</td></tr>
<tr><td>/3</td><td>(estable) casi todo es una chispa</td></tr>
<tr><td>1358/357</td><td>(caótico) un reino equilibrado de amebas</td></tr>
<tr><td>23/3</td><td>(caótico) "Juego de la Vida de Conway"</td></tr>
<tr><td>23/36</td><td>(caótico) "HighLife" (tiene replicante)</td></tr>
<tr><td>235678/3678</td><td>(estable) mancha de tinta que se seca rápidamente</td></tr>
<tr><td>34/34</td><td>(crece) "Vida 34"</td></tr>
</tbody></table></div><div style="text-align: center;"><br />
</div><br />
<div style="text-align: center;"><span style="font-size: large;"><strong>Descarga el código fuente desde </strong></span><a href="http://www.mediafire.com/file/9n5wnxfz7gig4fq/JVida%20Fast%20CSharp%20-%20Src.rar"><span style="font-size: large;"><strong>Aquí</strong></span></a></div><div style="text-align: center;">Si sólo quieres el ejecutable: <a href="http://www.mediafire.com/file/qky6bihifiwwmba/JVida%20Fast%20CSharp%20-%20Bin.rar">Aquí</a></div><div style="text-align: center;"><br />
</div><div style="text-align: center;">Notas: Necesitarás el <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992">.NET Framework 4.0</a> para poder correr el simulador.</div><div style="text-align: center;"><br />
</div><div style="text-align: center;"><span style="font-size: large;"><strong>Aquí: </strong></span><a href="http://gols.codeplex.com/"><span style="font-size: large;"><strong>http://gols.codeplex.com</strong></span></a><span style="font-size: large;"><strong> la última versión en inglés</strong></span></div><div style="text-align: left;"><br />
</div><div style="text-align: left;"><br />
</div><div style="text-align: left;"><br />
</div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-58762319531974040552011-03-18T21:23:00.000-07:002011-03-18T21:30:03.221-07:00Herramientas de comparación y merge en TFSLos que usamos TFS (Team Foundation Server) para el control de código fuente, sabemos que la herramienta de merge por defecto (Diffmerge) es bastante pobre. <br />
<br />
Por suerte Visual Studio 2010 permite configurar el software para comparaciones y merge de código que hagamos dentro de TFS.<br />
<br />
Aquí les ofrezco una breve comparación entre Diffmerge y otras dos populares herramientas (WinMerge y KDiff), además de los pasos necesarios para configurarlas dentro de Visual Studio. <br />
<br />
<br />
<strong><span style="font-size: large;"><a href="http://www.sourcegear.com/diffmerge/">Diffmerge (TFS)</a></span></strong><br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-P3ZePChXZZpQKttgxMrC1GSal8blIlVbR3su6W7W6ryXcs0rWa4ComN7ODSAsXC3xcpRBLeerm3nXpa0fWkrXPQrTe4hUoPpnojJZSt_ZhH2gZ-NwV5ou9-iKDlTef9OFWv5mxttnReE/s1600/tfs1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="306" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-P3ZePChXZZpQKttgxMrC1GSal8blIlVbR3su6W7W6ryXcs0rWa4ComN7ODSAsXC3xcpRBLeerm3nXpa0fWkrXPQrTe4hUoPpnojJZSt_ZhH2gZ-NwV5ou9-iKDlTef9OFWv5mxttnReE/s640/tfs1.png" width="640" /></a></div>• Es la herramienta por defecto del TFS para comparaciones y merges.<br />
• No hay posibilidad de cambiar el tamaño de la fuente.<br />
• La visibilidad del cambio es por línea, no se indica la parte de la línea que cambió.<br />
• Interfaz poco intuitiva y no configurable.<br />
<br />
<br />
<strong><a href="http://sourceforge.net/projects/kdiff3"><span style="font-size: large;">KDiff3</span></a> </strong>(sourceforge) <br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyux-yfn6SaFs9H5bGWo8WH1OcSA718KoUxrKXY91JNrYZWeWWtOCn_-ZihfbBrBh6CvHXFmpty2X4JHV1_NUr8gY9tFtt9v4_NgX4J580T_RO47MjDvXaE8BNzG_w5VmcJNRrSTtwM4UG/s1600/tfs2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="306" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyux-yfn6SaFs9H5bGWo8WH1OcSA718KoUxrKXY91JNrYZWeWWtOCn_-ZihfbBrBh6CvHXFmpty2X4JHV1_NUr8gY9tFtt9v4_NgX4J580T_RO47MjDvXaE8BNzG_w5VmcJNRrSTtwM4UG/s640/tfs2.png" width="640" /></a></div>• Posibilidad de cambiar el tamaño de la fuente para mayor visibilidad.<br />
• Los cambios se resaltan con códigos de colores en la parte de la línea que sufrió cambios.<br />
• La parte inferior muestra claramente los conflictos que deben ser resueltos manualmente.<br />
• Interfaz configurable.<br />
• Es open source (GNU GENERAL PUBLIC LICENSE)<br />
<br />
<br />
<div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><strong><a href="http://winmerge.org/"><span style="font-size: large;">WinMerge</span></a></strong><span style="font-size: large;"> </span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjka6uUkdHEk2Mx_cezVSSVR7tgYqKhm9fDTbPZWU7dwywjYFIHvDFRLp4Ql7IYJQ7KBpJ_yAWwi2Q7LElL6Spb5rZn9ES6aUCxtfHX1VzOSlWRYDrun535V8kGvUGP_AmNW-wwuc9k_HQw/s1600/tfs3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="262" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjka6uUkdHEk2Mx_cezVSSVR7tgYqKhm9fDTbPZWU7dwywjYFIHvDFRLp4Ql7IYJQ7KBpJ_yAWwi2Q7LElL6Spb5rZn9ES6aUCxtfHX1VzOSlWRYDrun535V8kGvUGP_AmNW-wwuc9k_HQw/s640/tfs3.png" width="640" /></a></div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">• Posibilidad de cambiar el tamaño de la fuente para mayor visibilidad.</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">• Los cambios se resaltan con colores en la parte de la línea que sufrió cambios.</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">• La parte inferior muestra claramente la diferencia en el conflicto seleccionado.</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">• Permite visualizar rápidamente todos los cambios del archivo.</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">• Es open source (GNU GENERAL PUBLIC LICENSE)</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">• Interfaz configurable.</div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><br />
</div>Estas dos últimas herramientas (<em>WinMerge</em> y <em>KDiff</em>) son bastante similares y oferecen prácticamente la misma funcionalidad, pero sin duda son las mejores herramientas de merge para Windows.<br />
Cuestión de gusto o costumbre cuál prefiera cada uno.<br />
<br />
<em></em><strong><span style="font-size: large;"><a href="http://sourceforge.net/projects/kdiff3">Para configurar el KDiff</a></span></strong> (o cualquier otra herramienta de merge) dentro del Visual Studio, se procede de la siguiente manera:<br />
<div class="MsoNormal" style="margin: 0cm 0cm 0pt 18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt; text-indent: -18pt;"><br />
<span style="mso-ansi-language: ES-MX;"><span style="mso-list: Ignore;">1. Dentro de </span></span><span lang="EN-US">VS2010, menú <i style="mso-bidi-font-style: normal;">Tools</i>, <i style="mso-bidi-font-style: normal;">Options</i>. </span><span style="mso-ansi-language: ES-MX;">Navegar hasta la opción <i style="mso-bidi-font-style: normal;">Source Control</i>, <i style="mso-bidi-font-style: normal;">Visual Studio TFS</i>. Click en el botón <i style="mso-bidi-font-style: normal;">Configure User Tools</i>.</span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsfACrmgFNaBCSvSQruazG6sjZTWtbLWTiNABCiZoJ1A-JhpwNpTn7WiFseDw2c7EOO9-K08AaqGYZfozaHnlW7m7Dm72FWeGyNy-bAGqZYteEa-cDPD6tVPYtMidTLsA8iBpmO3Z_mHuA/s1600/tfs4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="235" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsfACrmgFNaBCSvSQruazG6sjZTWtbLWTiNABCiZoJ1A-JhpwNpTn7WiFseDw2c7EOO9-K08AaqGYZfozaHnlW7m7Dm72FWeGyNy-bAGqZYteEa-cDPD6tVPYtMidTLsA8iBpmO3Z_mHuA/s400/tfs4.png" width="400" /></a></div><br />
<div class="MsoNormal" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; margin: 0cm 0cm 0pt 18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt; text-indent: -18pt;"><span style="mso-ansi-language: ES-MX;"><span style="mso-list: Ignore;">2. </span></span><span style="mso-ansi-language: ES-MX;">En <i style="mso-bidi-font-style: normal;">Configure User Tools</i>, agregar un nuevo comando con el botón <i style="mso-bidi-font-style: normal;">Add</i>, para asociar el comando de <i style="mso-bidi-font-style: normal;"></i></span><br />
<span style="mso-ansi-language: ES-MX;"><i style="mso-bidi-font-style: normal;">Compare</i>.</span></div><div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0cebeezb73b02fG0SxHUt84K-gTrT5xOIFok36jWElr35F9gSOrODmh8G8g6CPraDYVO24v6VRxLGNXbuAYWFNN_aQjxQwkh8iOi8TTMVzvlnvuSidkeJ6hDEIGhy7WsMWl9mj8zsXIFY/s1600/tfs5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="196" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0cebeezb73b02fG0SxHUt84K-gTrT5xOIFok36jWElr35F9gSOrODmh8G8g6CPraDYVO24v6VRxLGNXbuAYWFNN_aQjxQwkh8iOi8TTMVzvlnvuSidkeJ6hDEIGhy7WsMWl9mj8zsXIFY/s320/tfs5.png" width="320" /></a></div><div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: left;"><br />
</div><div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: left;">3. Ingresar los siguientes valores del comando de <em>compare</em> y darle OK:</div><blockquote><strong>Extension</strong>: * <br />
<strong>Operation</strong>: Compare<br />
<strong>Command</strong>: Ruta del ejecutable kdiff3<br />
<div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><strong>Arguments</strong>: %1 --fname %6 %2 --fname %7</div></blockquote><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDDkA71T_TuiGnFa929Qx9vdyPTywtCNtuigCsIMgyEW1264qIH9JwZmgbrrMf1pba8etJe1lLqTuiQn8rnaVtK3bwmdzQnwmsIrd5orp-PXkb0ij1Lc2fdobdlWtOWMzn8Xw-ZE8pyUAD/s1600/tfs6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDDkA71T_TuiGnFa929Qx9vdyPTywtCNtuigCsIMgyEW1264qIH9JwZmgbrrMf1pba8etJe1lLqTuiQn8rnaVtK3bwmdzQnwmsIrd5orp-PXkb0ij1Lc2fdobdlWtOWMzn8Xw-ZE8pyUAD/s320/tfs6.png" width="320" /></a></div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><br />
4. Agregar otra nueva operación con el botón Add, esta vez para asociar el comando <em>Merge</em>, e ingresar los siguientes valores.</div><blockquote><strong>Extension</strong>: * <br />
<strong>Operation</strong>: Merge<br />
<strong>Command</strong>: Ruta del ejecutable kdiff3<br />
<div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><strong>Arguments</strong>: %3 --fname %8 %2 --fname %7 %1 --fname %6 -o %4</div></blockquote><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7FDh29G-9flw3lGN_ECMLbP2q_5LQyJKgor7eOsZNtvAafGtGPXtQn2CrfhQoCTEvfCzPAWFyaOW51Gx9mB0mzrTTwCAqLflw5JzbK-0-JcrfjXuVykhM4t97sECOE44BgFEsPrm24-uY/s1600/tfs7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="176" r6="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7FDh29G-9flw3lGN_ECMLbP2q_5LQyJKgor7eOsZNtvAafGtGPXtQn2CrfhQoCTEvfCzPAWFyaOW51Gx9mB0mzrTTwCAqLflw5JzbK-0-JcrfjXuVykhM4t97sECOE44BgFEsPrm24-uY/s320/tfs7.png" width="320" /></a></div><div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"><br />
</div><br />
<div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="mso-ansi-language: ES-MX;">Listo, con esta configuración las comparaciones y merges que el TFS necesite hacer, se harán a través de la herramienta <em>KDiff3</em>.</span></div><div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><br />
</div><div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><br />
</div><div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="mso-ansi-language: ES-MX;"><strong><span style="font-size: large;"><a href="http://winmerge.org/">Para configurar el <em>WinMerge</em></a></span></strong> se procede de la misma forma, lo único que cambia es el <em>comando</em> y los <em>argumentos</em> de los últimos dos pasos, quedando así:</span></div><span style="mso-ansi-language: ES-MX;"></span><span style="mso-ansi-language: ES-MX;"></span><br />
<blockquote><div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="mso-ansi-language: ES-MX;"><strong>Extension</strong>: * </span></div><strong>Operation</strong>: Compare<br />
<strong>Command</strong>: <span style="mso-ansi-language: ES-MX;">winmerge.exe</span><br />
<strong>Arguments</strong>: /ub /dl %6 /dr %7 %1 %2</blockquote><blockquote><div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><strong>Extension</strong>: * </div><strong>Operation</strong>: Merge<br />
<strong>Command</strong>: winmerge.exe<br />
<strong>Arguments</strong>: /ub /dl %6 /dr %7 %1 %2 %4</blockquote><div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><br />
<a href="http://blogs.msdn.com/b/jmanning/archive/2006/02/20/diff-merge-configuration-in-team-foundation-common-command-and-argument-values.aspx"><span style="font-size: large;">Aquí</span></a><span style="font-size: large;"> transcribo una lista de herramientas</span> con los argumentos que deben utilizarse para integrarlas con <em>Visual Studio</em>:</div><div class="MsoNormal" style="margin: 0cm 0cm 0pt;"><table border="1"><tbody>
<tr><th colspan="3">Compare</th></tr>
<tr><th>Herramienta</th><th>Command</th><th>Arguments</th></tr>
<tr><td>TFS default</td><td>diffmerge.exe</td><td>%1 %2 %6 %7 %5 /ignorespace</td></tr>
<tr><td><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tools/tools/windiff.asp" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tools/tools/windiff.asp">WinDiff</a></td><td>windiff.exe</td><td>%1 %2</td></tr>
<tr><td><a href="http://www.softinterface.com/MD/MD.htm" mce_href="http://www.softinterface.com/MD/MD.htm">DiffDoc (for Word files)</a></td><td>DiffDoc.exe</td><td>/M%1 /S%2</td></tr>
<tr><td><a href="http://winmerge.sourceforge.net/" mce_href="http://winmerge.sourceforge.net/">WinMerge</a></td><td>winmerge.exe</td><td>/ub /dl %6 /dr %7 %1 %2</td></tr>
<tr><td><a href="http://www.scootersoftware.com/" mce_href="http://www.scootersoftware.com/">Beyond Compare</a></td><td>bc2.exe</td><td>%1 %2 /title1=%6 /title2=%7</td></tr>
<tr><td><a href="http://kdiff3.sourceforge.net/" mce_href="http://kdiff3.sourceforge.net/">KDiff3</a></td><td>kdiff3.exe</td><td>%1 --fname %6 %2 --fname %7</td></tr>
<tr><td><a href="http://www.araxis.com/merge/command_line.html" mce_href="http://www.araxis.com/merge/command_line.html">Araxis</a></td><td>compare.exe</td><td>/wait /2 /title1:%6 /title2:%7 %1 %2</td></tr>
<tr><td><a href="http://www.grigsoft.com/wincmp.htm" mce_href="http://www.grigsoft.com/wincmp.htm">Compare It!</a></td><td>Wincmp3.exe</td><td>%1 /=%6 %2 /=%7</td></tr>
<tr><td><a href="http://www.sourcegear.com/diffmerge/downloads.html" mce_href="http://www.sourcegear.com/diffmerge/downloads.html">SourceGear DiffMerge</a></td><td>DiffMerge.exe</td><td>/title1=%6 /title2=%7 %1 %2</td></tr>
<tr><td><a href="http://www.scootersoftware.com/beta3/" mce_href="http://www.scootersoftware.com/beta3/">Beyond Compare 3</a></td><td>BComp.exe</td><td>%1 %2 /title1=%6 /title2=%7</td></tr>
<tr><td><a href="http://tortoisesvn.tigris.org/TortoiseMerge.html" mce_href="http://tortoisesvn.tigris.org/TortoiseMerge.html">TortoiseMerge</a></td><td>TortoiseMerge.exe</td><td>/base:%1 /mine:%2 /basename:%6 /minename:%7</td></tr>
<tr><td><a href="http://www.slickedit.com/" mce_href="http://www.slickedit.com/">Visual SlickEdit</a></td><td>win\vsdiff.exe</td><td>%1 %2</td></tr>
</tbody></table><br />
<table border="1" style="height: 186px; width: 570px;"><tbody>
<tr><th colspan="3"><strong>Merge</strong></th></tr>
<tr><th>Herramienta</th><th><em>Command</em></th><th><em>Arguments</em></th></tr>
<tr><td>TFS default</td><td>diffmerge.exe</td><td>/merge %1 %2 %3 %4 %6 %7</td></tr>
<tr><td><a href="http://kdiff3.sourceforge.net/" mce_href="http://kdiff3.sourceforge.net/">KDiff3</a></td><td>kdiff3.exe</td><td>%3 --fname %8 %2 --fname %7 %1 --fname %6 -o %4</td></tr>
<tr><td><a href="http://msdn.microsoft.com/ssafe/" mce_href="http://msdn.microsoft.com/ssafe/">Visual SourceSafe</a></td><td>ssexp.exe</td><td>/merge %1 %2 %3 %4 %6 %7</td></tr>
<tr><td><a href="http://www.araxis.com/" mce_href="http://www.araxis.com/">Araxis</a></td><td>compare.exe</td><td>/wait /swap /a3 /3 /title1:%6 /title2:%7 /title3:%8 %1 %2 %3 %4</td></tr>
<tr><td><a href="http://www.scootersoftware.com/" mce_href="http://www.scootersoftware.com/">Beyond Compare (2-way merge)</a></td><td>bc2.exe</td><td>%1 %2 /savetarget=%4 /title1=%6 /title2=%7</td></tr>
<tr><td><a href="http://winmerge.sourceforge.net/" mce_href="http://winmerge.sourceforge.net/">WinMerge (2-way merge)</a></td><td>winmerge.exe</td><td>/ub /dl %6 /dr %7 %1 %2 %4</td></tr>
<tr><td><a href="http://www.guiffy.com/" mce_href="http://www.guiffy.com/">Guiffy</a></td><td>guiffy.exe</td><td>-s -h1%6 -h2%7 -hm%9 %1 %2 %3 %4</td></tr>
<tr><td><a href="http://www.elliecomputing.com/Home/default.asp">Ellie Computing</a></td><td>guimerge.exe</td><td>--mode=merge3 %3 %1 %2 --to=%4 --title0=%8 --title1=%6 --title2=%7 --to-title=%9</td></tr>
<tr><td><a href="http://www.sourcegear.com/diffmerge/downloads.html" mce_href="http://www.sourcegear.com/diffmerge/downloads.html">SourceGear DiffMerge</a></td><td>DiffMerge.exe</td><td>/title1=%6 /title2=%8 /title3=%7 /result=%4 %1 %3 %2</td></tr>
<tr><td><a href="http://www.scootersoftware.com/beta3/" mce_href="http://www.scootersoftware.com/beta3/">Beyond Compare 3</a></td><td>BComp.exe</td><td>%1 %2 %3 %4 /title1=%6 /title2=%7 /title3=%8 /title4=%9</td></tr>
<tr><td><a href="http://tortoisesvn.tigris.org/TortoiseMerge.html" mce_href="http://tortoisesvn.tigris.org/TortoiseMerge.html">TortoiseMerge</a></td><td>TortoiseMerge.exe</td><td>/base:%3 /mine:%2 /theirs:%1 /basename:%8 /minename:%7 /theirsname:%6 /merged:%4 /mergedname:%9</td></tr>
<tr><td><a href="http://www.slickedit.com/" mce_href="http://www.slickedit.com/">Visual SlickEdit</a></td><td>win\vsmerge.exe</td><td>%3 %1 %2 %4</td></tr>
</tbody></table><br />
<br />
<br />
</div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-12698655505763330312011-02-01T21:04:00.000-08:002011-02-01T21:04:27.389-08:00Visual Studio Addin para operaciones con TFS<a href="http://en.wikipedia.org/wiki/Team_Foundation_Server">Microsoft TFS</a> (Team Foundation Server) es un producto de Microsoft para el control de código fuente, elementos de trabajo y administración de proyectos.<br />
A pesar de que es una herramienta bastante completa y que está totalmente integrada al IDE de Visual Studio, en mi opinión, esta integración carece de accesos rápidos a operaciones básicas que a veces hacen perder un poco el tiempo.<br />
<br />
Por ejemplo, si queremos ubicar a un archivo dentro del control de código fuente, debemos navegar "manualmente" el árbol de archivos del servidor en la ventana <em>Source Control Explorer</em>. <br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmmNrs7iJWcfxScnP19oeRGJ28GIf-7oEpgihh3rZZQLf4NCcLhdaYiPzsOf2lJcIcqtkayCuBn8MtZP8j8sQ7gUZiS4KdczhmWSaHoP1kecm20DWXjt5H65iKP-A8uVPrXUkHLnqCqqc5/s1600/SCE.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="227" s5="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmmNrs7iJWcfxScnP19oeRGJ28GIf-7oEpgihh3rZZQLf4NCcLhdaYiPzsOf2lJcIcqtkayCuBn8MtZP8j8sQ7gUZiS4KdczhmWSaHoP1kecm20DWXjt5H65iKP-A8uVPrXUkHLnqCqqc5/s320/SCE.gif" width="320" /></a></div><br />
Sería muy práctico poder acceder a un archivo del servidor directamente desde el <em>Solution Explorer</em>.<br />
Ésta es una de las dos cosas que permite este Addin. Agrega menúes contextuales para poder acceder rápidamente a un archivo dentro del <em>Source Control Explorer </em>así como a la historia del mismo.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjccl1W_DqMT9-p5Yf0PAFEaGwUHkDZSobjqFV0OwLHtwk1Sx6uM256fVVNRPCXE1DheNgP4TWqKX2zJPMbaPz6hsPysPvQGM_4EheE8faufYo5vDzJQecPXcIszOt6NW7qlHBvKzOkSH-T/s1600/addin1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="301" s5="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjccl1W_DqMT9-p5Yf0PAFEaGwUHkDZSobjqFV0OwLHtwk1Sx6uM256fVVNRPCXE1DheNgP4TWqKX2zJPMbaPz6hsPysPvQGM_4EheE8faufYo5vDzJQecPXcIszOt6NW7qlHBvKzOkSH-T/s320/addin1.png" width="320" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi3-WMGfnBz_-AbAl1ssZbBaPLygt1azivZR3R2VosD-uhpSVknaICi7a2kAdTInAzonxZf0lAmu5Fsc7qydSiTjBoZkbwvmtFl_pyU85vB7QBfuhk1oXy38HQwVrQUNyes9utquBchYer/s1600/Addin2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="216" s5="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi3-WMGfnBz_-AbAl1ssZbBaPLygt1azivZR3R2VosD-uhpSVknaICi7a2kAdTInAzonxZf0lAmu5Fsc7qydSiTjBoZkbwvmtFl_pyU85vB7QBfuhk1oXy38HQwVrQUNyes9utquBchYer/s320/Addin2.PNG" width="320" /></a></div><br />
<br />
Actualmente existe un Addin mucho más completo (<a href="http://tfsplus.codeplex.com/">TFSPlus</a>) que permite estas dos cosas (y algunas más), pero hasta el momento no existe una versión que funcione en Visual Studio 2010.<br />
<br />
<blockquote>Para crear un Addin en Visual Studio 2010, podemos crear un nuevo proyecto de tipo <em>Visual Studio Addin</em> y se generará automáticamente la clase <em>Connect</em>, necesaria para la implementación de cualquier Addin.<br />
<a href="http://www.c-sharpcorner.com/uploadfile/mgold/addins11292005015631am/addins.aspx">Aquí</a> hay un tutorial al respecto que está muy bien explicado, así que me limitaré sólo al código para manejar los objetos de TFS.</blockquote>Para poder acceder a los objetos de TFS, necesitamos algunas referencias a librerías que están en los namespaces <em>Microsoft.VisualStudio.TeamFoundation</em>, y <em>Microsoft.TeamFoundation.</em> Normalmente se instalan en la <a href="http://en.wikipedia.org/wiki/Global_Assembly_Cache">GAC</a> al instalar Visual Studio 2010. Pero también se pueden encontrar en <em>C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0.</em><br />
<br />
<blockquote><a href="http://blogs.msdn.com/b/edhintz/archive/2006/02/03/524312.aspx">Aquí</a> hay un ejemplo (un poco viejo pero vigente) de cómo crear un addin para comunicarse con TFS en VS2005.</blockquote>La clase principal para acceder a la funcionalidad de <em>Version Control </em>de TFS se llama <em>VersionControlExt.</em> Para obtener una referencia a esta clase, podemos utilizar el objeto <em>application</em> que se recibe en el método <em>OnConnect</em> de la clase <em>Connect</em> de nuestro addin:<br />
<br />
<pre class="brush: csharp">public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
DTE2 applicationObject = (DTE2)application;
VersionControlExt vc = applicationObject.GetObject("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") as VersionControlExt;
...</pre><br />
Para ubicar y mostrar un archivo en el <em>Source Control Explorer</em> de TFS, se puede proceder de la siguiente forma:<br />
<br />
<pre class="brush: csharp">string localPath = applicationObject.SelectedItems.Item(1).ProjectItem.FileNames[0];
string serverPath = vc.Explorer.Workspace.GetServerItemForLocalItem(localPath);
vc.Explorer.Navigate(serverPath);
applicationObject.ExecuteCommand("View.TfsSourceControlExplorer");
</pre><div class="brush: csharp">En la primera línea se obtiene la ruta local del primer archivo seleccionado en el <em>Solution Explorer</em>.<br />
<br />
Luego se llama al método <em>GetServerItemForLocalItem</em> que obtene la ruta del archivo en el servidor a partir de su ruta local.</div><div class="brush: csharp">La tercera línea provoca que se seleccione el archivo en el <em>Source Control Explorer</em> de TFS.</div><div class="brush: csharp">La cuarta línea es sólo para asegurar que la ventana del explorador esté abierta y enfocada.</div><div class="brush: csharp"><br />
Adicionalmente se muestra el código necesario para mostrar la historia de un archivo (aunque esta opción ya existe en VS2010 en el menú contextual <em>view history</em>):<br />
<br />
<pre class="brush: csharp">VersionControlHistoryExt history = vc.History;
string localPath = applicationObject.SelectedItems.Item(1).ProjectItem.FileNames[0];
history.Show(localPath, VersionSpec.Latest, 0, RecursionType.Full);
</pre><br />
En la primera línea, se obtiene una referencia a la clase <em>VersionControlHistoryExt </em>que nos permite manipular el History de los archivos en el repositorio.<br />
La tercerá línea provoca que se muestre la historia del archivo seleccionado.<br />
<br />
<br />
<span style="font-size: large;">La versión completa del Addin se puede descargar desde </span><a href="http://www.mediafire.com/file/776l67lv8rt6gde/TFSAddIn.rar"><span style="font-size: large;">Aquí</span></a><span style="font-size: large;">.</span><br />
<br />
</div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-9069726686040518682011-01-09T19:58:00.000-08:002011-01-09T19:58:45.918-08:00Clipboard To Speech. Sintetizar el texto del portapapeles en C#Clipboard 2 Speech es una pequeña aplicación en C# que observa el contenido del clipboard (o portapapeles) y cuando detecta cualquier texto en él, lo "<a href="http://es.wikipedia.org/wiki/S%C3%ADntesis_de_habla">sintetiza vocalmente</a>" (Text-To-Speech). <br />
<br />
Utiliza la clase <strong><a href="http://msdn.microsoft.com/es-es/library/system.speech.synthesis.speechsynthesizer.aspx?appId=Dev10IDEF1&l=ES-ES&k=k(DIV);k(VS.TOOLBOX);k(TargetFrameworkMoniker-">SpeechSynthesizer</a> </strong>del namespace <strong>System.Speech.Synthesis </strong>de .NET. <br />
No es mucha la documentación que se puede encontrar de esta clase en MSDN, pero su uso es extremadamente sencillo; con sólo dos líneas de código, el sintetizador estará hablando:<br />
<br />
<pre class="brush: csharp">SpeechSynthesizer ss = new SpeechSynthesizer();
ss.Speak("Hello, this is a test");
</pre><div class="brush: csharp">Para el monitoreo del contenido del clipboard, se creó la clase <strong>ClipboardWatcher</strong> (basada en un ejemplo de <a href="http://www.developer.com/net/csharp/article.php/3359891/C-Tip-Monitoring-Clipboard-Activity-in-C.htm#steps">Tom Archer</a>) que utiliza la función <a href="http://msdn.microsoft.com/es-es/library/ms649052(v=VS.85).aspx"><strong>SetClipboardViewer</strong></a> de la API de windows, con el fin de suscribirnos al sistema operativo para que nos envíe un mensaje cada vez que el contenido de clipboard se modifique.<br />
<br />
Esta es la forma correcta de enlazarnos a la cadena del clipboard:</div><pre class="brush: csharp">private IntPtr nextClipboardViewer;
const int WM_DRAWCLIPBOARD = 0x308;
const int WM_CHANGECBCHAIN = 0x030D;
[DllImport("User32.dll")]
protected static extern int SetClipboardViewer(int hWndNewViewer);
[DllImport("User32.dll")]
public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
public ClipboardWatcher() // Constructor
{
nextClipboardViewer = (IntPtr)SetClipboardViewer((int)this.Handle);
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
OnClipboardData();
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
case WM_CHANGECBCHAIN:
if (m.WParam == nextClipboardViewer)
nextClipboardViewer = m.LParam;
else
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
default:
base.WndProc(ref m);
break;
}
}
protected override void Dispose(bool disposing)
{
ChangeClipboardChain(this.Handle, nextClipboardViewer);
}
</pre>Este código debe estar dentro de un control de windows forms que implemente la función <a href="http://msdn.microsoft.com/en-us/library/ms633573.aspx">WndProc</a>, (por ejemplo un Form o un UserControl).<br />
<br />
Hasta aquí sólo obtenemos un aviso cada vez que el contenido del clipboard se modifica, por eso en el método <strong>OnClipboardData</strong> debemos obtener el nuevo contenido mediante una llamada al método estático <strong><a href="http://msdn.microsoft.com/es-es/library/system.windows.forms.clipboard.getdataobject(v=VS.90).aspx">GetDataObject</a> </strong>de la clase <strong>Clipboard </strong>(de<strong> </strong>System.Windows.Form), y a partir de esto se dispara un evento con algunos datos del contenido del clipboard:<br />
<br />
<pre class="brush: csharp">private void OnClipboardData()
{
ClipboardDataArgs args = new ClipboardDataArgs();
try
{
args.Data = Clipboard.GetDataObject();
if (args.Data.GetDataPresent(DataFormats.Text))
{
args.Text = (string)args.Data.GetData(DataFormats.Text);
}
else if (args.Data.GetDataPresent(DataFormats.Bitmap))
{
args.Image = (Bitmap)args.Data.GetData(DataFormats.Bitmap);
}
OnRaiseClipboardData(args);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
</pre><pre class="brush: csharp">public class ClipboardDataArgs : EventArgs
{
public string Text { get; set; }
public Bitmap Image { get; set; }
public IDataObject Data { get; set; }
}
</pre><br />
Simple...<br />
<br />
<span style="font-size: large;">Puedes descargar el código completo desde </span><a href="http://www.mediafire.com/?mb6nb3xrgme1unh"><span style="font-size: large;">aquí</span></a><span style="font-size: large;">.</span><br />
<br />
<strong>Nota:</strong><br />
La aplicación acepta ciertos "comandos" desde el clipboard. Por ejemplo, puedes copiar la cadena "/pause" o "/stop" para que el sintetizador se detenga, o la cadena "/start" para que reanude la síntesis.Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-20580113356258677522010-12-24T20:05:00.000-08:002010-12-24T20:17:07.045-08:00Monitorear las ventanas que se abren y cierran en windows mediante un system hookAquí se presenta una forma de monitorear las ventanas de Windows a medida que se crean y destruyen, en C#.<br />
<br />
Si no te interesa seguir leyendo, <a href="http://www.mediafire.com/?i6ibh9czzca6dq3">aquí</a> puedes bajar el código completo de la aplicación.<br />
<br />
<strong><span style="font-size: large;">Introducción</span></strong><br />
<br />
Dentro de Windows, toda interacción entre ventanas y con el usuario (clicks, movimiento de cursor, etc) se hace a través de mensajes. <br />
<br />
Las aplicaciones tienen la capacidad de escuchar y procesar cada uno de los mensajes, por ejemplo, para minimizarse, maximizarse o cerrarse cuando el usuario hace click en el botón correspondiente de la parte superior derecha de la ventana. <br />
<br />
En general, una aplicación Windows Forms en .NET, no tiene la necesidad de procesar explícitamente los mensajes, ya que la mayoría de las interacciones se produce automáticamente o por medio de eventos comunes de cada control (Click, Load, etc). <br />
<br />
Pero para procesar los mensajes explícitamente, se utiliza una técnica denominada hooking que consiste en hacer que nuestra aplicación implemente un <em>método</em> y lo informe al sistema operativo. Este <em>método</em> será en realidad una función de callback (callback function) y funcionará como un "gancho" (hook) para interceptar los mensajes y poder procesarlos.<br />
<br />
Así, cuando Windows procese un evento "enganchable", como el movimiento del cursor o la creación de una ventana, llamará inmediatamente a la función de callback que nuestra aplicación defina.<br />
En el caso de Windows Forms, el método (la función de callback) que intercepta los mensajes, se denomina <em>WndProc</em> y tiene la siguiente firma:<br />
<pre class="brush: csharp">void WndProc(ref System.Windows.Forms.Message m)
</pre><br />
<strong><span style="font-size: large;">Ejemplo</span></strong><br />
<br />
Se presenta una aplicación simple que mostrará en tiempo real una lista con las ventanas, a medida que se van creando o destruyendo.<br />
Para esto, se implementará un hook a nivel shell, para que cada vez que se cree o destruya una ventana, el sistema operativo pase el control a una subrutina de nuestra aplicación y así poder informar al usuario del evento.<br />
<br />
A continuación se muestra el código necesario para registrar nuestra aplicación como gancho (o hook) de los mensajes del <a href="http://es.wikipedia.org/wiki/Windows_Shell">shell de windows</a> en un Window Form en C#.<br />
<pre class="brush: csharp">uMsgNotify = Win32API.RegisterWindowMessage("SHELLHOOK");
Win32API.RegisterShellHookWindow(this.Handle);
</pre><br />
La llamada a <a href="http://msdn.microsoft.com/en-us/library/ms644947(VS.85).aspx">RegisterWindowMessage</a> se hace para obtener un identificador único de los mensajes. Este identificador lo necesitaremos dentro de la función de callback para identificar a los mensajes que nos interesa escuchar.<br />
La llamada a <a href="http://msdn.microsoft.com/en-us/library/ms644989(VS.85).aspx">RegisterShellHookWindow</a> se hace para registrar nuestro WinForm como gancho de los eventos del shell de windows.<br />
<br />
Una vez hecho esto, procedemos a sobreescribir la función de callback en nuestro WinForm, para interceptar los mensajes de <a href="http://msdn.microsoft.com/en-us/library/ms644991(VS.85).aspx">WindowCreated</a> y <a href="http://msdn.microsoft.com/en-us/library/ms644991(VS.85).aspx">WindowDestroyed</a>, como se muestra a continuación:<br />
<pre class="brush: csharp">protected override void WndProc(ref System.Windows.Forms.Message m)
{
IntPtr hWnd;
if (m.Msg == uMsgNotify)
{
switch (m.WParam.ToInt32())
{
case (int)Win32API.ShellEvents.HSHELL_WINDOWCREATED:
hWnd = m.LParam;
// La ventana cuyo handler es hWnd, fue creada
...
break;
case (int)Win32API.ShellEvents.HSHELL_WINDOWDESTROYED:
hWnd = m.LParam;
// La ventana cuyo handler es hWnd, fue cerrada
...
break;
}
}
base.WndProc(ref m);
}
</pre><div class="brush: csharp"><br />
Lo único que resta por hacer, es obtener el nombre de la ventana que fue creada/destruida, así como el nombre del proceso (ejecutable) al que pertenece, todo a partir del identificador de la ventana (hWnd). </div><div class="brush: csharp"><br />
Para obtener el nombre de la ventana a partir de su identificador, utilizamos la función <a href="http://msdn.microsoft.com/en-us/library/ms633521(VS.85).aspx">GetWindowTextLength</a> y <a href="http://msdn.microsoft.com/en-us/library/ms633520(VS.85).aspx">GetWindowText</a> como se muestra a continuación:</div><pre class="brush: csharp">private string GetWindowName(IntPtr hwnd)
{
StringBuilder sb = new StringBuilder();
int longi = Win32API.GetWindowTextLength(hwnd) + 1;
sb.Capacity = longi;
Win32API.GetWindowText(hwnd, sb, sb.Capacity);
return sb.ToString();
}
</pre><br />
Obtener el nombre del ejecutable al que pertenece la ventana es un poco más tedioso, ya que se necesitan 4 llamadas a la API:<br />
<br />
<pre class="brush: csharp">private string ExePathFromHwnd(IntPtr hWnd)
{
StringBuilder sb = new StringBuilder(Win32API.MAX_PATH);
int pid = 0;
Win32API.GetWindowThreadProcessId(hWnd, ref pid);
IntPtr hProc = Win32API.OpenProcess(Win32API.ProcessAccess.AllAccess, false, pid);
if (hProc != IntPtr.Zero)
{
uint lRet = Win32API.GetModuleFileNameEx(hProc, IntPtr.Zero, sb, Win32API.MAX_PATH);
Win32API.CloseHandle(hProc);
}
return sb.ToString();
}
</pre><br />
Juntando todo esto en una aplicación, podemos generar algo así:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://www.mediafire.com/?i6ibh9czzca6dq3"><img border="0" height="219" n4="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhweorKJDo2qQQzWL6RMLAvpNDQV0z2rjWSLbynKmUnm9GY8RrEN0RBfj4CQ2zTKW-djwmBU25vywCE3iPRSTo7AIkhy0AQKxkA5VPIl8HBg2y1hGryXLtR2RXcZvHeouyw2YGr734XOjQb/s640/ProcessHook.jpg" width="640" /></a></div><br />
<a href="http://www.mediafire.com/?i6ibh9czzca6dq3"><span style="font-size: large;">Aquí</span></a><span style="font-size: large;"> puedes bajar el código completo de la aplicación.</span><br />
<br />
Feliz navidad !Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com1tag:blogger.com,1999:blog-8699577164878004669.post-43624376982399090752010-11-29T10:11:00.000-08:002011-01-07T21:15:20.963-08:00Orden lexicográfico de combinaciones matemáticas en C#.Aquí se presenta un algoritmo en C# para obtener el <strong>índice lexicográfico</strong> de una <strong>combinación de elementos </strong>y vice-versa (una combinación a partir de su índice lexicográfico).<br />
<br />
<div></div>"Los <a href="http://es.wikipedia.org/wiki/Combinaciones"><b>coeficientes binomiales</b> o <b>combinaciones</b></a> indican el número de formas en que se pueden extraer subconjuntos a partir de un conjunto dado." (wikipedia)<br />
<br />
<div></div><div><strong>Ejemplo</strong>:</div><div>Se tiene un conjunto con 6 objetos diferentes {1,2,3,4,5,6}, de los cuales se desea escoger 2 (sin importar el orden de elección). Existen 15 formas de efectuar tal elección. <br />
<blockquote>C(n,k) = n! / k! (n - k)! => C(6,2) = 15</blockquote><br />
<br />
A continuación se listan estas 15 formas, en orden lexicográfico: <br />
(1,2) (1,3) (1,4) (1,5) (1,6) <br />
(2,3) (2,4) (2,5) (2,6) <br />
(3,4) (3,5) (3,6) <br />
(4,5) (4,6) <br />
(5,6) <br />
<br />
Así, por ejemplo, la séptima combinación en orden lexicográfico es la (2,4).<br />
<br />
Podría decirse que el orden lexicográfico está dado por la tasa de cambio entre los elementos. Por ejemplo el elemento (1,3) difiere en sólo una unidad con respecto a (1,2), y es lexicográficamente el número 2. Así, el número de cambios y la posición del elemento cambiado definen de alguna manera el orden lexicográfico. <br />
<br />
Sea <strong>n </strong>la cantidad de objetos de los que se puede elegir y <strong>k </strong>la cantidad de objetos que se eligen, el algoritmo que se presenta a continuación, generará un arreglo de elementos (una combinación) a partir del valor del índice lexicográfico i. <br />
<br />
O sea, el método retornará el vector (2,4), con las entradas n=6, k=2, i=7.<br />
<br />
<pre><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">int</span>[] GetOrderedSetByIndex(<span style="color: blue;">int</span> n, <span style="color: blue;">int</span> k, <span style="color: blue;">int</span> i)
{
<span style="color: blue;">if</span> (k == 1) <span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: blue;">int</span>[] { i };
<span style="color: blue;">int</span>[] arr = <span style="color: blue;">new</span> <span style="color: blue;">int</span>[k];
<span style="color: blue;">int</span> r, m = 0;
<span style="color: blue;">for</span> (<span style="color: blue;">int</span> j = 0; j < k - 1; j++)
{
arr[j] = (j != 0) ? arr[j - 1] : 0;
<span style="color: blue;">do</span>
{
arr[j]++;
r = choose(n - arr[j], k - (j + 1));
m = m + r;
} <span style="color: blue;">while</span> (m < i);
m = m - r;
}
arr[k - 1] = arr[k - 2] + i - m;
<span style="color: blue;">return</span> arr;
}</pre></div><span style="font-size: x-small;">NOTA: El método <em>choose </em>no se lista pero se puede descargar el código completo desde <a href="http://www.mediafire.com/?ilfxzgxbm1smprl">aquí</a>.</span><br />
<div><br />
Para el ejemplo anterior, la llamada al método que obtiene la combinación (2,4) sería: <span style="font-size: xx-small;">GetOrderedSetByIndex(6, 2, 7) </span><br />
<br />
<br />
<br />
<span style="font-size: small;">De igual forma, se presenta el método inverso, para obtener el índice lexicográfico a partir de una combinación dada:</span></div><br />
<pre><span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">int</span> GetIndexByOrderedSet(<span style="color: blue;">int</span> n, <span style="color: blue;">int</span> k, <span style="color: blue;">int</span>[] comb)
{
<span style="color: blue;">int</span>[] C = <span style="color: blue;">new</span> <span style="color: blue;">int</span>[k];
<span style="color: blue;">long</span> LI = 0, R;
<span style="color: blue;">for</span> (<span style="color: blue;">int</span> i = 1; i <= k - 1; i++)
{
C[i - 1] = 0;
<span style="color: blue;">if</span> (i != 1)
C[i - 1] = C[i - 2];
<span style="color: blue;">do</span>
{
C[i - 1] = C[i - 1] + 1;
R = combine(n - C[i - 1], k - i);
LI = LI + R;
} <span style="color: blue;">while</span> ((C[i - 1] < comb[i - 1]));
LI = LI - R;
}
<span style="color: blue;">return</span> (<span style="color: blue;">int</span>)LI + comb[k - 1] - comb[k - 2];
}</pre><div></div><pre><span style="font-size: x-small;"><span style="color: #5c5c5c;"><blockquote></blockquote></span></span> </pre><span style="font-size: x-small;">NOTA: El método <em>combine</em> no se lista pero sólamente calcula el coeficiente binomial. El código completo se puede descargar desde <a href="http://www.mediafire.com/?ilfxzgxbm1smprl">aquí</a>.</span><br />
<br />
Para el ejemplo anterior, la llamada al método que obtiene el índice lexicográfico sería: <span style="color: blue; font-size: xx-small;"><span style="color: blue; font-size: xx-small;"></span></span><span style="font-size: xx-small;">GetIndexByOrderedSet(6, 2, </span><span style="color: blue; font-size: xx-small;"><span style="color: blue; font-size: xx-small;">new</span></span><span style="font-size: xx-small;"> </span><span style="color: blue; font-size: xx-small;"><span style="color: blue; font-size: xx-small;">int</span></span><span style="font-size: xx-small;">[] { 2, 4 });</span> y retornaría 7.<br />
<br />
<br />
<br />
<span style="font-size: xx-small;"><span style="font-size: small;">Estos métodos son útiles también para listar lexicográficamente todas las combinaciones dados un valor de <strong>n</strong> y <strong>k</strong>, como se muestra a continuación:</span></span><br />
<br />
<pre><span style="color: blue;">for</span> (<span style="color: blue;">int</span> i = 1; i <= combine(6, 2); i++)
{
<span style="color: blue;">int</span>[] comb = GetOrderedSetByIndex(6, 2, i);
Console.WriteLine(<span style="color: firebrick;">"({0},{1})"</span>, comb[0], comb[1]);
}</pre><br />
<br />
<span style="font-size: large;">El código completo se puede bajar desde <a href="http://www.mediafire.com/?ilfxzgxbm1smprl">aquí</a>.</span><br />
<span style="font-size: xx-small;"><span style="font-size: small;">Espero que alguien le sea útil.</span></span><br />
<br />
<span style="font-size: xx-small;"><span style="font-size: small;">Federico D. Colombo </span></span><span style="font-size: xx-small;"><span style="font-size: x-small;">NOTA: </span></span><br />
<span style="font-size: xx-small;"><span style="font-size: x-small;">Los algoritmos presentados aquí están basados en el </span><a href="http://portal.acm.org/citation.cfm?id=355739"><span style="font-size: x-small;">Algoritmo 515 de Buckles</span></a><span style="font-size: x-small;">.</span></span><br />
<span style="font-size: xx-small;"><span style="font-size: x-small;"></span><br />
<br />
<span style="font-size: x-small;">Vínculos:</span><br />
<span style="font-size: x-small;"><br />
</span><a href="http://msdn.microsoft.com/en-us/library/aa289166.aspx"><span style="font-size: x-small;">http://msdn.microsoft.com/en-us/library/aa289166.aspx</span></a><br />
<a href="http://saliu.com/lexicographic.html"><span style="font-size: x-small;">http://saliu.com/lexicographic.html</span></a><br />
<a href="http://www.calculatorsoup.com/calculators/discretemathematics/combinations.php"><span style="font-size: x-small;">http://www.calculatorsoup.com/calculators/discretemathematics/combinations.php</span></a></span><br />
<span style="font-size: x-small;"></span>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-67002288341176445782010-09-19T18:53:00.000-07:002010-12-20T20:13:10.797-08:00Visor de Procesos y Ventanas de Windows en vb6Aquí comparto una aplicación en vb6 que hice hace unos años pero que aún se sigue ganando un acceso directo en mi escritorio:<br />
<br />
"Procesos y Ventanas" no es más que otro (más) visor de procesos y ventanas de windows.<br />
Funciona en casi cualquier versión del Windows. (Al menos en todas las que lo probé: XP, Vista, 2003, 2008, 7).<br />
<br />
Así se ve:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd-v2C5JsG_FMpXuJRj9QhQE33SSfouQ8LoSpYOS8DZRuxKkbtxVHCO-n2HFmrZ63U32Hla1FSXB8Map8pJbEbt97F_Ts9TRFKtBn3i318vUuf-6YHUv7C033GXrMqVdHDuUwMgMDVtBVN/s1600/Procesos.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" qx="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd-v2C5JsG_FMpXuJRj9QhQE33SSfouQ8LoSpYOS8DZRuxKkbtxVHCO-n2HFmrZ63U32Hla1FSXB8Map8pJbEbt97F_Ts9TRFKtBn3i318vUuf-6YHUv7C033GXrMqVdHDuUwMgMDVtBVN/s320/Procesos.JPG" /></a></div><br />
Tiene algunas funcionalidades que lo hacen útil como la posibilidad de arrastrar el puntero del mouse hasta cualquier ventana para poder seleccionarla en el grid. <br />
El botón TopMost permite colocar la ventana siempre en primer plano (útil cuando se necesita copiar y pegar desde múltiples fuentes, etc). <br />
El botón Mostrar permite mostrar una ventana que por defecto permanezca oculta.<br />
El botón MATAR permite terminar un proceso cualquiera.<br />
Permite enviar mensajes típicos (maximize, minimize, hide, show) a cualquier ventana.<br />
Otra opción interesante es la posibilidad de cambiar el padre (contenedor) de una ventana para lograr algo como esto (la ventana de Google Earth contenida dentro de la ventana del Explorer) :<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgExQvHeC4Asskp4-STqZz29RKnAT6a-HjLSu0S9_wCTQ6izd_I9Rulm1f-Kc-IU2FAi8pPJ3Wp_GtcvoMhDx8p_5XzY_C_8PEPf1eXQbCSkBVxjAuVatSYHp9f-Kgr_Rr7qH3hRxXEb4LI/s1600/ggg.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" qx="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgExQvHeC4Asskp4-STqZz29RKnAT6a-HjLSu0S9_wCTQ6izd_I9Rulm1f-Kc-IU2FAi8pPJ3Wp_GtcvoMhDx8p_5XzY_C_8PEPf1eXQbCSkBVxjAuVatSYHp9f-Kgr_Rr7qH3hRxXEb4LI/s320/ggg.JPG" /></a></div><br />
A mi siempre me fue útil esta herramienta y espero que alguien por ahi también.<br />
<br />
<span style="font-size: large;">Puedes bajar el código en vb6 desde </span><span style="font-size: large;"><a href="http://www.mediafire.com/?6n6ldfpst1kl27b">Aquí</a></span><span style="font-size: large;">.</span><br />
<br />
necesitarás msvbvm60.dll y msflxgrid.dll (Microsoft FlexGrid Control 6.0 (SP3))<br />
<br />
Suerte.Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-10306115537380141482010-09-03T09:13:00.000-07:002010-12-20T20:19:35.126-08:00Presentación de curso "Cubos OLAP"<span style="font-size: large;"><a href="http://www.mediafire.com/?5yr73ehg2ytactc">Aquí</a> adjunto el material del mini-curso "Cubos OLAP".</span><br />
<br />
<div></div><div></div><div></div><div></div>El paquete incluye la presentación en PDF, los scripts de datos del ejemplo, un examen con sus respectivas respuestas y un documento extra con información para migrar un cubo de Microsoft AS2000 a AS2005.<br />
<br />
<div></div><div></div><div></div>Contenido de la presentación:<br />
<ul><li>Definición</li>
<li>Ejemplos</li>
<li>Jerarquías</li>
<li>Ventajas y desventajas</li>
<li>Diseño (star y snowflake)</li>
<li>Arquitectura ROLAP, MOLAP y HOLAP</li>
</ul><br />
<div><div></div>Screenshot:</div><div class="separator" style="clear: both; text-align: center;"></div><div><br />
<div></div><div></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf_I5QEJwXfMR_EYFvMcL508eY6ZFJawXsTsfo_Ecdp9CsQdcOLAyQxdQIjOzzcQl4C0_BOJTcGvme1YURbjXRK-rH3yziwSwrCeM8k0ouXB11jm-FOJXTV8DZYXKMErK6t0tWmjnKKcQ5/s1600/cubo.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf_I5QEJwXfMR_EYFvMcL508eY6ZFJawXsTsfo_Ecdp9CsQdcOLAyQxdQIjOzzcQl4C0_BOJTcGvme1YURbjXRK-rH3yziwSwrCeM8k0ouXB11jm-FOJXTV8DZYXKMErK6t0tWmjnKKcQ5/s320/cubo.JPG" /></a></div><div></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div></div><div class="separator" style="clear: both; text-align: center;"></div><div></div><div class="separator" style="clear: both; text-align: center;"><br />
</div></div><div></div><div class="separator" style="clear: both; text-align: center;"></div><div></div><div>Descárgalo <a href="http://www.mediafire.com/?5yr73ehg2ytactc">aquí</a>.</div><br />
<div></div><div></div><div></div><div></div><br />
<div></div><div></div><div></div><div></div><div>Espero que a alguien le sea de utilidad.</div><div></div><br />
<div></div><div></div><div></div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-72518434753004457452010-09-03T09:03:00.000-07:002010-12-20T20:16:41.130-08:00Presentación de curso "Novedades en Transact-SQL 2005"<span style="font-size: large;"><a href="http://www.mediafire.com/?jrqrkgjt0di4ccf">Aquí</a> adjunto el material del mini-curso "Novedades en T-SQL 2005".</span><br />
<br />
<div></div><div></div><div></div>El paquete incluye la presentación de Powerpoint, y el código con los scripts demos.<br />
<br />
<div></div><div></div>Contenido de la presentación:<br />
<ul><li>Manejo de errores. TRY/CATCH.</li>
<li>Instrucciones INTERSECT y EXCEPT.</li>
<li>Instrucción TOP basada en expresión.</li>
<li>Instrucción OUTPUT y OUTPUT INTO.</li>
<li>ON DELETE y ON UPDATE en llaves foráneas.</li>
<li>CTE (Common table expressions) reutilización de querys, recursividad.</li>
<li>Muestreo de tablas. Instrucción TABLESAMPLE.</li>
<li>Pivoteo de tablas. PIVOT y UNPIVOT.</li>
<li>Funciones de Ranking y Partitioning.</li>
<li>Integración con CLR (.NET)</li>
</ul><div> </div><div>Este curso está orientado a las nuevas características que ofrece el lenguaje de script Transact-SQL de Microsoft a partir de la versión SQL 2005.</div><div></div><div><br />
<div></div><br />
<div></div>Screenshots:</div><div class="separator" style="clear: both; text-align: center;"></div><div><br />
<div></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqTiykQYi8atlGBfNGSZ-gWiu1DWOnrnLgpYF00VlRoibLkyJcFyOUeGl9W76WpqOl1ua1WYk-EkPyGzoftU8eJ1gZKkrWVBteAKXOlzrzE5BDlTaMcFXUO8lnW29cB0PsMpBD_KLiZrpG/s1600/sql2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqTiykQYi8atlGBfNGSZ-gWiu1DWOnrnLgpYF00VlRoibLkyJcFyOUeGl9W76WpqOl1ua1WYk-EkPyGzoftU8eJ1gZKkrWVBteAKXOlzrzE5BDlTaMcFXUO8lnW29cB0PsMpBD_KLiZrpG/s320/sql2.JPG" /></a></div><div></div><div class="separator" style="clear: both; text-align: center;"></div><div></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkned9PWMTnDJt68mGolR_FSADBQaTPHR9rdiUycQKNp5BiW3XKTGWukCM6hF535ZL7gxH46BiaFfIzaNUwj7vtsu6bV8uMgyNbZWc4mpLJ2WLFQgSBCMPVTqLMIIEQPhcXBpoH6B4Cj9a/s1600/sql1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkned9PWMTnDJt68mGolR_FSADBQaTPHR9rdiUycQKNp5BiW3XKTGWukCM6hF535ZL7gxH46BiaFfIzaNUwj7vtsu6bV8uMgyNbZWc4mpLJ2WLFQgSBCMPVTqLMIIEQPhcXBpoH6B4Cj9a/s320/sql1.JPG" /></a></div></div><div></div><div class="separator" style="clear: both; text-align: center;"></div><div></div><div>Descárgalo <a href="http://www.mediafire.com/?jrqrkgjt0di4ccf">aquí</a>.</div><br />
<div></div><div></div><div></div><br />
<div></div><div></div><div></div><div>Espero que a alguien le sea de utilidad.</div><div></div><br />
<div></div><div></div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-45330043867650369042010-09-02T20:31:00.000-07:002010-12-20T20:14:30.886-08:00Presentación de curso "Introducción a LINQ"<span style="font-size: large;"><a href="http://www.mediafire.com/?s20jd6apqx3o7ru">Aquí</a> adjunto el material del mini-curso "Introducción a LINQ" (Language INtegrated Queries).</span><br />
<br />
<div></div><div></div>El paquete incluye la presentación de Powerpoint, y bastante código con ejemplos y cosas interesantes en VB.<br />
<br />
<div></div><div>Contenido de la presentación:</div><ul><li>Proyecciones (select)</li>
<li>Filtros</li>
<li>Ordenamiento</li>
<li>Joins</li>
<li>Agrupamiento</li>
<li>Operadores de elemento (first, last, single)</li>
<li>Métodos de agregación (sum, min, max)</li>
<li>Cuantificadores (any, all, contains)</li>
<li>LINQ to SQL</li>
<li>DataContext</li>
<li>Transacciones</li>
</ul><br />
<div>Este curso está orientado al uso de LINQ en Visual Basic.</div><div></div><div><br />
<br />
Screenshots:</div><div class="separator" style="clear: both; text-align: center;"></div><div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOr9aGQrgOs27g3akrcTKarSu4F8BZ2Y7Gic0lufXAX01_eCjeYUWiaD1DgvBWcwaYWmTiWTBkjhOBc8dT4oJwDU7FcbW7opY9OeUn_Az4DQV8hm80WbMGYcqSEJh-kZVUlVY8qw1uAERY/s1600/linq1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOr9aGQrgOs27g3akrcTKarSu4F8BZ2Y7Gic0lufXAX01_eCjeYUWiaD1DgvBWcwaYWmTiWTBkjhOBc8dT4oJwDU7FcbW7opY9OeUn_Az4DQV8hm80WbMGYcqSEJh-kZVUlVY8qw1uAERY/s320/linq1.JPG" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiogMjMLUKUWINlMqhBIklJGl2Z_XV7sdkwq6dXBgW-XUZaf355n1gbevuCji7fROkpodRzHU8pgh-uYnPQBBFaWqGslKo7a2crXoIlQGCd6bgDnEm4OLLkMnwIExFzK1bqY4T_W07-CACb/s1600/linq2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiogMjMLUKUWINlMqhBIklJGl2Z_XV7sdkwq6dXBgW-XUZaf355n1gbevuCji7fROkpodRzHU8pgh-uYnPQBBFaWqGslKo7a2crXoIlQGCd6bgDnEm4OLLkMnwIExFzK1bqY4T_W07-CACb/s320/linq2.JPG" /></a></div></div><div></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div>Descárgalo <a href="http://www.mediafire.com/?s20jd6apqx3o7ru">aquí</a>.</div><br />
<div></div><div></div><br />
<div></div><div></div><div>Espero que a alguien le sea de utilidad.</div><div></div><br />
<div></div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-41683486755148977992010-09-02T20:20:00.000-07:002010-12-20T20:15:01.714-08:00Presentación de curso "Novedades en .NET Framework 3.5 (VB9)"<span style="font-size: large;"><a href="http://www.mediafire.com/?6hnurdm7ph4vj41">Aquí</a> adjunto el material del mini-curso "Novedades en .NET Framework 3.5".</span><br />
<br />
<div></div>El paquete incluye la presentación de Powerpoint, el examen con sus respectivas respuestas, el código con los ejemplos en VB, un póster en formato .PDF con los <em>tipos</em> más importantes del .NET framework 3.5 y una nota de El Guille (Guillermo Som) acerca de los <em>Generics</em> en VB9.<br />
<br />
<div>Contenido de la presentación:</div><ul><li>Inferencia de tipos </li>
<li>Tipos anónimos (new with) </li>
<li>Inicialización de objetos </li>
<li>Iteradores </li>
<li>Colecciones genéricas </li>
<li>Tipos genéricos </li>
<li>Clases parciales </li>
<li>Expresiones lambda </li>
<li>Métodos extensores </li>
<li>Sobrecarga de operadores </li>
<li>Tipos por valor anulables </li>
<li>Operador ternario If </li>
<li>Relajación de delegados </li>
<li>Comentarios XML </li>
</ul><br />
<br />
Screenshots:<br />
<div class="separator" style="clear: both; text-align: center;"></div><div></div><div></div><div class="separator" style="clear: both; text-align: center;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig-5G4GBjSnyTkJWnNmEDqg9FBFIjRt_tjPbznn_FHtgZHcX2S78o7OjJEPhXxf8Gp7DhU6iXLo7m4IibEDIpCnnw1taIR47uqS-8d8FMn3cY8tiUfYw4rSgh3n4aL38o1EtzEV7t5gEtI/s320/vb9_1.JPG" /></div><br />
<div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ4jSu_kcqrLgM08PfkdYR5oZ-IIDgwh5sOSRE48HgV7ghYCeGgOMtw_mjO4gmsyC9c7vGRSRtQ03iJ_1NBcpt3PSClqCM8GCvHel2no74XW7U7YMIBRKvC32OooBJnfHYYgnvadY3WBEO/s1600/vb9_2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ4jSu_kcqrLgM08PfkdYR5oZ-IIDgwh5sOSRE48HgV7ghYCeGgOMtw_mjO4gmsyC9c7vGRSRtQ03iJ_1NBcpt3PSClqCM8GCvHel2no74XW7U7YMIBRKvC32OooBJnfHYYgnvadY3WBEO/s320/vb9_2.JPG" /></a></div><div></div><br />
<div></div>Descárgalo <a href="http://www.mediafire.com/?6hnurdm7ph4vj41">aquí</a>.<br />
<br />
<div></div><br />
<div></div><div>Espero que a alguien le sea de utilidad.</div><div></div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-45453371937360212742010-09-02T19:52:00.000-07:002010-12-20T20:15:25.653-08:00Presentación de curso "Aplicaciones multicapas"<span style="font-size: large;"><a href="http://www.mediafire.com/?3ccecdv3cfq0akc">Aquí</a> adjunto el material de un mini-curso de "Aplicaciones Multicapas".</span><br />
<br />
El paquete incluye la presentación de Powerpoint y el examen con sus respectivas respuestas.<br />
<br />
<div>Contenido de la presentación:</div><ul><li>Definición de Aplicación Multicapas</li>
<li>Capa de Presentación</li>
<li>Capa de Negocio</li>
<li>Capa de Datos o Persistencia</li>
</ul><br />
<br />
Screenshot:<br />
<div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt2S3h0CBlBsEX-T-z5C5s-FCYawOI87xBql2Uvg4UL639xyltiMI78ANA_QzuDpF2LPv0feLCcEAf0vjQP2Mlp3npJnaJM5MR-HpCuhoPpm-O7DlFiCE30kBhCBHGxuacFHPTOPf42i7A/s1600/capas1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt2S3h0CBlBsEX-T-z5C5s-FCYawOI87xBql2Uvg4UL639xyltiMI78ANA_QzuDpF2LPv0feLCcEAf0vjQP2Mlp3npJnaJM5MR-HpCuhoPpm-O7DlFiCE30kBhCBHGxuacFHPTOPf42i7A/s320/capas1.JPG" /></a></div><br />
<br />
Descárgalo <a href="http://www.mediafire.com/?3ccecdv3cfq0akc">aquí</a>.<br />
<br />
<br />
<div>Espero que a alguien le sea de utilidad.</div><div></div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-12068384527713320862010-09-02T19:40:00.000-07:002010-12-20T20:15:57.969-08:00Presentación de Curso "Programación Orientada a Objetos en .NET"<span style="font-size: large;"><a href="http://www.mediafire.com/?59p015nossr353m">Aquí</a> adjunto el material de un mini-curso de "Programación Orientada a Objetos en .NET".</span><br />
<br />
El paquete incluye la presentación de Powerpoint, el examen con sus respectivas respuestas y el código de los ejemplos en VB y C#.<br />
<br />
<br />
<div>Contenido de la presentación:</div><ul><li>Definición de la POO</li>
<li>Conceptos fundamentales de la POO</li>
<li>Clase</li>
<li>Objeto</li>
<li>Variables y métodos de clase</li>
<li>Herencia</li>
<li>Clases abstractas</li>
<li>Interfaces</li>
<li>Polimorfismo</li>
<li>Sobrecarga de funciones</li>
<li>Sobrecarga de operadores</li>
</ul><br />
<br />
Screenshots:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvOwGHfonbm-UDCM1LxtfZ_U3jemWFcLOuRNKxyXuuyTttyAbnlYBhS_hQYBeIgAqqXeO2IN5XWslSIswq0_X2iYwmgXSf0WQI3768zTsGP7KMU36rgtBL4fhdI4JyS-IC1uGkbAD9Gda7/s1600/pooNET.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvOwGHfonbm-UDCM1LxtfZ_U3jemWFcLOuRNKxyXuuyTttyAbnlYBhS_hQYBeIgAqqXeO2IN5XWslSIswq0_X2iYwmgXSf0WQI3768zTsGP7KMU36rgtBL4fhdI4JyS-IC1uGkbAD9Gda7/s320/pooNET.JPG" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEz_viPADb39al30fkMkUl2_Q-hx0hHJzB1GvxIwG66h6YfzB0EI0RCMeR2pwrl6fD3Lc4iX-n8RMNufHDBC4TwLdKPFuchKWXbKrsztj1w0pubotO7po4WrV1W6wXfI4SZuha0iiRJBNK/s1600/pooNET2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" ox="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEz_viPADb39al30fkMkUl2_Q-hx0hHJzB1GvxIwG66h6YfzB0EI0RCMeR2pwrl6fD3Lc4iX-n8RMNufHDBC4TwLdKPFuchKWXbKrsztj1w0pubotO7po4WrV1W6wXfI4SZuha0iiRJBNK/s320/pooNET2.JPG" /></a></div><br />
<br />
Descárgalo <a href="http://www.mediafire.com/?59p015nossr353m">aquí</a>.<br />
<br />
<br />
<div>Espero que a alguien le sea de utilidad.</div><div></div>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-2126675720409909342010-07-20T20:16:00.000-07:002010-12-20T20:23:51.759-08:00LINQ2Sql: Modificar dinámicamente el nombre de una tabla en un DataContext de LINQ.<span style="font-size: 85%;">Ya van varias veces que veo preguntas de cómo hacer para cambiar dinámicamente el nombre de una tabla de un mapeo de LINQ.<br />
<br />
Algunas aplicaciones crean nuevas tablas dinámicamente a medida que, por algún motivo, las van necesitando. Estas nuevas tablas se crean a partir de una tabla molde o "base".<br />
Dicho de otra manera: Se tiene una base de datos en la que <strong>n</strong> tablas tienen el mismo esquema y sólo difieren en su nombre y, se desea poder mapear dichas tablas con un único DataContext que pueda ser instanciado dinámicamente según la tabla que se quiera consultar.<br />
<br />
La misma idea se puede aplicar para el nombre de una base de datos o cualquier otro objeto de SQL.</span><span style="font-size: 85%;"></span><br />
<blockquote><span style="font-size: 85%;">NOTA: Los ejemplos de esta entrada están en inglés porque inicialmente fue la respuesta de este </span><a href="http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/f5e0af64-0057-4498-998b-70db656a0e9f"><span style="font-size: 85%;">thread</span></a><span style="font-size: 85%;"> de MS</span></blockquote><br />
<span style="font-size: 85%;">EL PROBLEMA:<br />
<br />
Por defecto, el mapeo de LINQ se lleva a cabo mediante atributos y, como tales, no pueden ser modificados en tiempo de ejecución.<br />
Pero por suerte el constructor de la clase DataContext de LINQ tiene una sobrecarga con el parámetro mappingSource, que nos permite obtener el DataContext a partir de un mapeo externo (que puede ser un archivo .xml).<br />
<br />
CASO DE EJEMPLO:<br />
<br />
Se tiene la tabla base <em>Person</em>, y otras dos tablas más llamadas <em>Person_1</em> y <em>Person_2</em>, todas con idéntica estructura.<br />
<br />
A continuación se lista el script que crea estas tablas:</span><span style="font-size: 85%;"></span><br />
<div style="background-color: lightgrey; color: black;"><br />
<pre><span style="font-size: 78%;"><span style="color: blue;">Use</span> [DB_Test]
GO
<span style="color: blue;">Create</span> <span style="color: blue;">Table</span> dbo.Person
(
ID <span style="color: blue;">int</span> <span style="color: blue;">PRIMARY</span> <span style="color: blue;">KEY</span>,
<span style="color: blue;">Name</span> <span style="color: blue;">nvarchar</span>(<span style="color: magenta;">MAX</span>)
)
<span style="color: blue;">Create</span> <span style="color: blue;">Table</span> dbo.Person_1
(
ID <span style="color: blue;">int</span> <span style="color: blue;">PRIMARY</span> <span style="color: blue;">KEY</span>,
<span style="color: blue;">Name</span> <span style="color: blue;">nvarchar</span>(<span style="color: magenta;">MAX</span>)
)
<span style="color: blue;">Create</span> <span style="color: blue;">Table</span> dbo.Person_2
(
ID <span style="color: blue;">int</span> <span style="color: blue;">PRIMARY</span> <span style="color: blue;">KEY</span>,
<span style="color: blue;">Name</span> <span style="color: blue;">nvarchar</span>(<span style="color: magenta;">MAX</span>)
)
<span style="color: blue;">Insert</span> <span style="color: blue;">Into</span> dbo.Person <span style="color: blue;">Values</span> (1, <span style="color: #a31515;">'Base Table'</span>)
<span style="color: blue;">Insert</span> <span style="color: blue;">Into</span> dbo.Person_1 <span style="color: blue;">Values</span> (1, <span style="color: #a31515;">'Some data in Table_1'</span>)
<span style="color: blue;">Insert</span> <span style="color: blue;">Into</span> dbo.Person_2 <span style="color: blue;">Values</span> (1, <span style="color: #a31515;">'Some data in Table_2'</span>)</span>
</pre></div><br />
<span style="font-size: 85%;">SOLUCIÓN:<br />
<br />
La solución propuesta es mapear una única vez el esquema de la tabla y al momento de obtener el DataContext, especificar el nombre de la tabla que se quiere consultar.<br />
<br />
Lo primero que necesitamos es generar un archivo .dbml con el mapeo de la tabla "base" de la forma habitual (Add New Item -> LINQ to SQL classes).<br />
Como nombre le pondremos Person.dbml, por lo cual la clase generada se llamará PersonDataContext.<br />
El diagrama quedará así:</span><a href="http://s1039.photobucket.com/albums/a480/thepirat000/?action=view&current=1dbml.jpg" target="_blank"><img alt="dbml" border="0" src="http://i1039.photobucket.com/albums/a480/thepirat000/1dbml.jpg" /></a><br />
<br />
<span style="font-size: 85%;">Una vez generado el mapeo de la tabla base, procedemos a generar a partir de éste, un archivo .xml que también contendrá el mapeo.<br />
Para esto utilizaremos la herramienta sqlmetal.<br />
En línea de comandos de Visual Studio (Visual Studio Tools -> Visual Studio 2008 Command Prompt), ejecutar desde la carpeta donde se encuentra el archivo person.dbml:<br />
<strong>SqlMetal /map:person.xml /code person.dbml</strong><br />
Esto generará el archivo person.xml cuyo contenido será algo como:</span><br />
<br />
<pre lang="x-xml"><span style="font-size: 78%;"><?xml version="1.0" encoding="utf-8"?>
<Database Name="DB_Test" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
<Table Name="dbo.Person" Member="Persons">
<Type Name="Person">
<Column Name="ID" Member="ID" Storage="_ID" DbType="Int NOT NULL" IsPrimaryKey="true" />
<Column Name="Name" Member="Name" Storage="_Name" DbType="NVarChar(MAX)" />
</Type>
</Table>
</Database></span></pre><br />
<br />
<span style="font-size: 85%;">A continuación, es recomendable incluir el archivo person.xml en nuestro proyecto como recurso embebido, con las propiedades <em>Build Action=Enbedded Resource</em> y <em>Copy to Output Directory=Do not copy</em>, como se muestra a continuación:</span><br />
<a href="http://s1039.photobucket.com/albums/a480/thepirat000/?action=view&current=2addxml.jpg" target="_blank"><img alt="add" border="0" src="http://i1039.photobucket.com/albums/a480/thepirat000/2addxml.jpg" /></a><br />
<br />
<span style="font-size: 85%;">Ahora necesitamos generar un método que retorne el DataContext apuntando a una tabla en específico.<br />
Lo más cómodo es codificarlo en la misma clase (PersonDataContext).<br />
La forma más directa es parándonos sobre Person.dbml en el solution explorer y haciendo click en el botón View Code. Esto generará el archivo Person.cs con la clase PersonDataContext a la que le agregamos el método y queda así:</span><br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: blue;">namespace</span> DynamicDataContext
{
<span style="color: blue;">using</span> System.Linq;
<span style="color: blue;">using</span> System.Xml;
<span style="color: blue;">using</span> System.Xml.Linq;
<span style="color: blue;">using</span> System.Data.Linq.Mapping;
<span style="color: blue;">using</span> System.IO;
<span style="color: blue;">using</span> System.Reflection;
<span style="color: blue;">partial</span> <span style="color: blue;">class</span> PersonDataContext
{
<span style="color: blue;">private</span> <span style="color: blue;">const</span> <span style="color: blue;">string</span> CNN_STRING = <span style="color: firebrick;">"Data Source=.;Initial Catalog=DB_Test;Integrated Security=True"</span>;
<span style="color: blue;">public</span> <span style="color: blue;">static</span> PersonDataContext GetDataContext(<span style="color: blue;">string</span> tableName)
{
<span style="color: green;">// Get the .xml file into memory </span>
Stream ioSt = <span style="color: blue;">Assembly</span>.GetExecutingAssembly().GetManifestResourceStream(<span style="color: firebrick;">"DynamicDataContext.person.xml"</span>);
XElement xe = XElement.Load(XmlReader.Create(ioSt));
<span style="color: green;">// Replace the table name value in memory</span>
<span style="color: blue;">var</span> tableElements = xe.Elements().AsQueryable().<span style="color: blue;">Where</span>(e => e.Name.LocalName.Equals(<span style="color: firebrick;">"Table"</span>));
<span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> t <span style="color: blue;">in</span> tableElements)
{
<span style="color: blue;">var</span> nameAttribute = t.Attributes().<span style="color: blue;">Where</span>(a => a.Name.LocalName.Equals(<span style="color: firebrick;">"Name"</span>));
<span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> a <span style="color: blue;">in</span> nameAttribute)
{
<span style="color: blue;">if</span> (a.<span style="color: blue;">Value</span>.Equals(<span style="color: firebrick;">"dbo.Person"</span>))
{
a.<span style="color: blue;">Value</span> = a.<span style="color: blue;">Value</span>.Replace(<span style="color: firebrick;">"Person"</span>, tableName);
}
}
}
<span style="color: green;">// Obtain and return the dynamic DataContext</span>
XmlMappingSource source = XmlMappingSource.FromXml(xe.ToString());
<span style="color: blue;">return</span> <span style="color: blue;">new</span> PersonDataContext(CNN_STRING, source);
}
}
}</pre></div><span style="font-size: 85%;">Y eso es todo…<br />
Cada vez que necesitemos el datacontext, llamaremos al método GetDataContext recién creado pasándole el nombre de la tabla que nos interesa en ese momento:</span><br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main()
{
<span style="color: green;">// Query table Person_2 </span>
<span style="color: blue;">using</span> (PersonDataContext dc = PersonDataContext.GetDataContext(<span style="color: firebrick;">"Person_2"</span>))
{
Console.WriteLine(dc.Persons.First().Name);
}
<span style="color: green;">// Query table Person_1</span>
<span style="color: blue;">using</span> (PersonDataContext dc = PersonDataContext.GetDataContext(<span style="color: firebrick;">"Person_1"</span>))
{
Console.WriteLine(dc.Persons.First().Name);
}
<span style="color: green;">// Query table Person</span>
<span style="color: blue;">using</span> (PersonDataContext dc = PersonDataContext.GetDataContext(<span style="color: firebrick;">"Person"</span>))
{
Console.WriteLine(dc.Persons.First().Name);
}
<span style="color: green;">// Query default table (Person in this case)</span>
<span style="color: blue;">using</span> (PersonDataContext dc = <span style="color: blue;">new</span> PersonDataContext())
{
Console.WriteLine(dc.Persons.First().Name);
}
Console.ReadKey();
}</pre></div><br />
<br />
<span style="font-size: 130%;">-- Puedes bajar este ejemplo </span><a href="http://www.mediafire.com/?u3bzhsl474i50l8"><span style="font-size: 130%;">aquí</span></a><span style="font-size: 130%;"> --</span><br />
<br />
<br />
Suerte !<br />
<br />
Federico.Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com1tag:blogger.com,1999:blog-8699577164878004669.post-70737234360534934682010-07-09T20:08:00.000-07:002010-12-20T20:22:22.146-08:00Project Euler #144 solución en VB.NETResolución de <a href="http://projecteuler.net/index.php?section=problems&id=144">ejercicio #144 de Project Euler</a> en VB.NET.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZo97sgcLa88yrpb3eYv5NLH0ZGB1f-TkBbAMitF4ZZxvkB3BON2sEh3AQkufvms7NlWW6pZGNYLId9CFOmRU7rhsnl85Tbx0THObZNOo_kON6Z1_-FunqaqiojjpOdJrfxyEhdauCYArx/s1600/p_144_2.gif"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5492147501106624706" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZo97sgcLa88yrpb3eYv5NLH0ZGB1f-TkBbAMitF4ZZxvkB3BON2sEh3AQkufvms7NlWW6pZGNYLId9CFOmRU7rhsnl85Tbx0THObZNOo_kON6Z1_-FunqaqiojjpOdJrfxyEhdauCYArx/s320/p_144_2.gif" style="cursor: hand; float: left; height: 287px; margin: 0px 10px 10px 0px; width: 141px;" /></a><br />
<br />
<a href="http://projecteuler.net/index.php?section=problems&id=144">Este </a>es un interesante ejercicio que simula un sistema de espejos que reflejan un laser.<br />
<br />
El ejercicio consiste en averiguar cuántas veces el haz de un laser rebota dentro de una elipse antes de salir por un pequeño orificio de entrada/salida ubicado en la parte superior.<br />
<br />
Una forma de resolverlo es con un método (algoritmo, función) que, a partir del punto de colisión (sobre el que incide el laser en la elipse), calcule el próximo punto de colisión del haz siguiendo las <a href="http://es.wikibooks.org/wiki/F%C3%ADsica/%C3%93ptica/Leyes_de_la_reflexi%C3%B3n_y_de_la_refracci%C3%B3n">leyes de la reflexión</a>.<br />
El proceso continúa hasta que el punto de colisión obtenido pertenezca al orificio de entrada.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Para resolverlo, se utilizaron dos clases simples: <em>RectaR2</em> y <em>PuntoD</em>.<br />
La primera representa a una recta en el plano y la segunda representa a un punto en el plano:<br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: green;">'Clase para representar a una recta en el plano</span>
<span style="color: blue;">Public</span> <span style="color: blue;">Class</span> RectaR2
<span style="color: blue;">Public</span> P <span style="color: blue;">As</span> PuntoD
<span style="color: blue;">Public</span> m <span style="color: blue;">As</span> <span style="color: blue;">Double</span>
<span style="color: green;">'A partir de la pendiente y un punto incluido en la recta</span>
<span style="color: blue;">Sub</span> <span style="color: blue;">New</span>(<span style="color: blue;">ByVal</span> m <span style="color: blue;">As</span> <span style="color: blue;">Double</span>, <span style="color: blue;">ByVal</span> P <span style="color: blue;">As</span> PuntoD)
<span style="color: blue;">Me</span>.m = m
<span style="color: blue;">Me</span>.P = P
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>
<span style="color: green;">'A partir de dos puntos de la recta</span>
<span style="color: blue;">Sub</span> <span style="color: blue;">New</span>(<span style="color: blue;">ByVal</span> P1 <span style="color: blue;">As</span> PuntoD, <span style="color: blue;">ByVal</span> P2 <span style="color: blue;">As</span> PuntoD)
<span style="color: blue;">Dim</span> m <span style="color: blue;">As</span> <span style="color: blue;">Double</span> = (P2.Y - P1.Y) / (P2.X - P1.X)
<span style="color: blue;">Me</span>.m = m
<span style="color: blue;">Me</span>.P = P2
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>
<span style="color: green;">'Ecuacion Explicita</span>
<span style="color: blue;">Public</span> <span style="color: blue;">Overrides</span> <span style="color: blue;">Function</span> ToString() <span style="color: blue;">As</span> <span style="color: blue;">String</span>
<span style="color: blue;">Return</span> <span style="color: blue;">String</span>.Format(<span style="color: firebrick;">"y = {0}x + {1}"</span>, <span style="color: blue;">Me</span>.m, <span style="color: blue;">Me</span>.P.Y - <span style="color: blue;">Me</span>.m * <span style="color: blue;">Me</span>.P.X)
<span style="color: blue;">End</span> <span style="color: blue;">Function</span>
<span style="color: blue;">End</span> <span style="color: blue;">Class</span>
<span style="color: green;">'Clase para representar un punto en el plano</span>
<span style="color: blue;">Public</span> <span style="color: blue;">Class</span> PuntoD
<span style="color: blue;">Public</span> X <span style="color: blue;">As</span> <span style="color: blue;">Double</span>, Y <span style="color: blue;">As</span> <span style="color: blue;">Double</span>
<span style="color: blue;">Sub</span> <span style="color: blue;">New</span>()
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>
<span style="color: blue;">Sub</span> <span style="color: blue;">New</span>(<span style="color: blue;">ByVal</span> x <span style="color: blue;">As</span> <span style="color: blue;">Double</span>, <span style="color: blue;">ByVal</span> y <span style="color: blue;">As</span> <span style="color: blue;">Double</span>)
<span style="color: blue;">Me</span>.X = x
<span style="color: blue;">Me</span>.Y = y
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>
<span style="color: blue;">End</span> <span style="color: blue;">Class</span></pre></div>También se utilizó un método que denominé <em>Paso</em>, que calcula el siguiente punto de colisión del laser a partir del punto de colisión actual.<br />
<br />
Este método es el que contiene los cálculos trigonométricos necesarios para obtener la reflexión del laser.<br />
<br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: green;">'A partir de un punto de inicio y fin de un rayo laser (ambos en la elipse)</span>
<span style="color: green;">'retorna el proximo punto de contacto del laser (tambien en la elipse)</span>
<span style="color: blue;">Function</span> Paso(<span style="color: blue;">ByVal</span> Pini <span style="color: blue;">As</span> PuntoD, <span style="color: blue;">ByVal</span> Pfin <span style="color: blue;">As</span> PuntoD) <span style="color: blue;">As</span> PuntoD
<span style="color: blue;">Dim</span> SgtePunto <span style="color: blue;">As</span> <span style="color: blue;">New</span> PuntoD()
<span style="color: green;">'Calculo la pendiente de la recta tangente a la elipse en el Punto de Fin (m = 4x/y) (m1)</span>
<span style="color: blue;">Dim</span> m1 <span style="color: blue;">As</span> <span style="color: blue;">Double</span> = -4 * Pfin.X / Pfin.Y
<span style="color: green;">'Obtengo la pendiente de la recta reflejada (reflejo sobre la recta tangente)... Y = m2*X + b</span>
<span style="color: green;">'tmp = (m0-m1)/(1+m0*m1) m2 = (m1-X)/(1+X*m1)</span>
<span style="color: blue;">Dim</span> m0 <span style="color: blue;">As</span> <span style="color: blue;">Double</span> = (Pfin.Y - Pini.Y) / (Pfin.X - Pini.X)
<span style="color: blue;">Dim</span> tmp <span style="color: blue;">As</span> <span style="color: blue;">Double</span> = (m0 - m1) / (1 + m0 * m1)
<span style="color: blue;">Dim</span> m2 <span style="color: blue;">As</span> <span style="color: blue;">Double</span> = (m1 - tmp) / (1 + tmp * m1)
<span style="color: green;">'Obtengo los 2 puntos de interesección entre la recta reflejada y la elipse</span>
<span style="color: blue;">Dim</span> b <span style="color: blue;">As</span> <span style="color: blue;">Double</span> = Pfin.Y - Pfin.X * m2
<span style="color: blue;">Dim</span> CoordsX <span style="color: blue;">As</span> PuntoD = Cuadratica(4 + (m2 ^ 2), 2 * m2 * b, (b ^ 2) - 100)
<span style="color: green;">'Descartar el punto fin (Pfin)</span>
SgtePunto.X = <span style="color: blue;">If</span>(Math.Abs(CoordsX.Y - Pfin.X) < 0.001, CoordsX.X, CoordsX.Y)
SgtePunto.Y = m2 * SgtePunto.X + b
<span style="color: blue;">Return</span> SgtePunto
<span style="color: blue;">End</span> <span style="color: blue;">Function</span></pre></div>También se utilizó una forma para poder graficar el recorrido del laser en la pantalla:<br />
<br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: blue;">Public</span> <span style="color: blue;">Class</span> Form1
<span style="color: blue;">Private</span> bitmap <span style="color: blue;">As</span> Bitmap = <span style="color: blue;">New</span> Bitmap(500, 1000)
<span style="color: blue;">Sub</span> <span style="color: blue;">New</span>()
<span style="color: green;">' This call is required by the Windows Form Designer.</span>
InitializeComponent()
<span style="color: green;">'Dibujar la elipse</span>
<span style="color: blue;">Using</span> g <span style="color: blue;">As</span> Graphics = Graphics.FromImage(bitmap)
g.DrawEllipse(Pens.Blue, g.VisibleClipBounds)
<span style="color: blue;">End</span> <span style="color: blue;">Using</span>
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>
<span style="color: green;">'Convertir un punto del plano en un punto de la forma</span>
<span style="color: blue;">Public</span> <span style="color: blue;">Function</span> ConvertirPunto(<span style="color: blue;">ByVal</span> P0 <span style="color: blue;">As</span> PuntoD) <span style="color: blue;">As</span> PointF
<span style="color: blue;">Return</span> <span style="color: blue;">New</span> PointF(<span style="color: blue;">CSng</span>(250 + P0.X * 50), <span style="color: blue;">CSng</span>(500 - P0.Y * 50))
<span style="color: blue;">End</span> <span style="color: blue;">Function</span>
<span style="color: green;">'Dibujar un segmento de recta dado</span>
<span style="color: blue;">Public</span> <span style="color: blue;">Sub</span> DibujarRecta(<span style="color: blue;">ByVal</span> P0 <span style="color: blue;">As</span> PuntoD, <span style="color: blue;">ByVal</span> P1 <span style="color: blue;">As</span> PuntoD)
<span style="color: blue;">Using</span> g = Graphics.FromImage(bitmap)
g.DrawLine(Pens.Red, ConvertirPunto(P0), ConvertirPunto(P1))
<span style="color: blue;">Me</span>.PictureBox1.Image = bitmap
<span style="color: blue;">End</span> <span style="color: blue;">Using</span>
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>
<span style="color: green;">'Dibujar un número dado en la parte inferior</span>
<span style="color: blue;">Public</span> <span style="color: blue;">Sub</span> DibujarNum(<span style="color: blue;">ByVal</span> num <span style="color: blue;">As</span> <span style="color: blue;">Integer</span>)
<span style="color: blue;">Dim</span> pt1 <span style="color: blue;">As</span> <span style="color: blue;">New</span> PointF(450, 970)
<span style="color: blue;">Using</span> g = Graphics.FromImage(bitmap)
g.FillRectangle(Brushes.LightGray, pt1.X, pt1.Y, 50, 30)
g.DrawString(num.ToString, <span style="color: blue;">New</span> Font(<span style="color: firebrick;">"Verdana"</span>, 14.0!), Brushes.Black, pt1)
<span style="color: blue;">Me</span>.PictureBox1.Image = bitmap
<span style="color: blue;">End</span> <span style="color: blue;">Using</span>
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>
<span style="color: blue;">End</span> <span style="color: blue;">Class</span></pre></div>Y por último, la entrada principal de la aplicación, donde está el ciclo que efectúa la búsqueda de puntos de incidencia, el conteo y la orden de dibujar en pantalla:<br />
<br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: blue;">Sub</span> Main()
<span style="color: blue;">Dim</span> PIni <span style="color: blue;">As</span> <span style="color: blue;">New</span> PuntoD(0, 10.1)
<span style="color: blue;">Dim</span> PFin <span style="color: blue;">As</span> <span style="color: blue;">New</span> PuntoD(1.4, -9.6)
<span style="color: blue;">Dim</span> frm <span style="color: blue;">As</span> <span style="color: blue;">New</span> Form1
<span style="color: blue;">Dim</span> temp <span style="color: blue;">As</span> PuntoD
<span style="color: blue;">Dim</span> steps <span style="color: blue;">As</span> <span style="color: blue;">Integer</span> = 0
frm.Show()
<span style="color: blue;">While</span> PFin.Y < 0 <span style="color: blue;">OrElse</span> Math.Abs(PFin.X) > 0.01
frm.DibujarRecta(PIni, PFin)
frm.DibujarNum(steps)
Application.DoEvents()
temp = PIni
PIni = PFin
PFin = Paso(temp, PFin)
steps += 1
<span style="color: blue;">End</span> <span style="color: blue;">While</span>
MessageBox.Show(<span style="color: firebrick;">"Euler144="</span> & steps)
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span></pre></div>Espero a alguien le sea útil... Y sino, no importa...<br />
<br />
<br />
<br />
<span style="font-size: 130%;">-- Puedes bajar este ejemplo </span><a href="http://www.mediafire.com/?84y3hncmem0e7do"><span style="font-size: 130%;">aquí</span></a><span style="font-size: 130%;"> --</span>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-19610804223224628112009-05-29T11:42:00.000-07:002010-12-20T20:25:52.036-08:00Limitar la cantidad de instancias de una aplicación con VB.NET<strong>He aquí una clase para limitar la cantidad de instancias que pueden correrse de una aplicación.</strong><br />
<br />
- Funciona si se cambia el nombre del ejecutable o si se ejecuta desde diferentes ejecutables.<br />
- Funciona si la aplicación se cierra de forma anormal.<br />
- Es configurable por Máquina o por Sesión (útil para limitar por usuario cuando se utilizan Terminal Services).<br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: green;">'The-Pirat 2009</span>
<span style="color: blue;">Imports</span> System.Threading
<span style="color: green;">''' <summary></span>
<span style="color: green;">''' Enumerador para inicar el tipo de bloqueo</span>
<span style="color: green;">''' </summary></span>
<span style="color: blue;">Public</span> <span style="color: blue;">Enum</span> eTipo <span style="color: blue;">As</span> <span style="color: blue;">Integer</span>
POR_SESION = 0
[<span style="color: blue;">GLOBAL</span>] = 1
<span style="color: blue;">End</span> <span style="color: blue;">Enum</span>
<span style="color: green;">''' <summary></span>
<span style="color: green;">''' Clase para implementar un máximo M de instancias de la aplicación por cada usuario o por cada máquina</span>
<span style="color: green;">''' </summary></span>
<span style="color: blue;">Public</span> <span style="color: blue;">Class</span> InstanciaPrevia
<span style="color: blue;"> Private</span> <span style="color: blue;">Shared</span> _mutex <span style="color: blue;">As</span> Mutex
<span style="color: green;"> ''' <summary></span>
<span style="color: green;"> ''' Función que devuelve TRUE si ya se rebasó el límite de instancias del programa corriendo</span>
<span style="color: green;"> ''' </summary></span>
<span style="color: green;"> ''' <param name="Tipo">Tipo del bloqueo. Por usuario o global.</param></span>
<span style="color: blue;"> Public</span> <span style="color: blue;">Shared</span> <span style="color: blue;">Function</span> RebasaLimite(<span style="color: blue;">ByVal</span> Tipo <span style="color: blue;">As</span> eTipo, <span style="color: blue;">ByVal</span> Max <span style="color: blue;">As</span> <span style="color: blue;">Integer</span>) <span style="color: blue;">As</span> <span style="color: blue;">Boolean</span>
<span style="color: blue;"> Dim</span> NombreAssembly <span style="color: blue;">As</span> <span style="color: blue;">String</span> = System.Reflection.<span style="color: blue;">Assembly</span>.GetExecutingAssembly().GetName().Name
<span style="color: blue;"> For</span> i <span style="color: blue;">As</span> <span style="color: blue;">Integer</span> = 0 <span style="color: blue;">To</span> Max - 1
<span style="color: blue;"> If</span> CrearMutex(NombreAssembly, i, Tipo) <span style="color: blue;">Then</span>
<span style="color: blue;"> Return</span> <span style="color: blue;">False</span>
<span style="color: blue;"> End</span> <span style="color: blue;">If</span>
<span style="color: blue;"> Next</span>
<span style="color: blue;"> Return</span> <span style="color: blue;">True</span>
<span style="color: blue;"> End</span> <span style="color: blue;">Function</span>
<span style="color: green;"> ''' <summary></span>
<span style="color: green;"> ''' Intenta crear un nuevo mutex, devuelve true si NO existía previamente y se creó ahora</span>
<span style="color: green;"> ''' </summary></span>
<span style="color: blue;"> Private</span> <span style="color: blue;">Shared</span> <span style="color: blue;">Function</span> CrearMutex(<span style="color: blue;">ByVal</span> Nombre <span style="color: blue;">As</span> <span style="color: blue;">String</span>, <span style="color: blue;">ByVal</span> Index <span style="color: blue;">As</span> <span style="color: blue;">Integer</span>, <span style="color: blue;">ByVal</span> Tipo <span style="color: blue;">As</span> eTipo) <span style="color: blue;">As</span> <span style="color: blue;">Boolean</span>
<span style="color: green;"> 'Nombre del mutex según Tipo (visibilidad)</span>
<span style="color: blue;"> Dim</span> mutexName <span style="color: blue;">As</span> <span style="color: blue;">String</span> = <span style="color: blue;">If</span>(Tipo = eTipo.<span style="color: blue;">GLOBAL</span>, <span style="color: firebrick;">"Global\"</span>, <span style="color: firebrick;">"Local\"</span>) & Nombre & Index.ToString()
<span style="color: blue;"> Dim</span> newMutexCreated <span style="color: blue;">As</span> <span style="color: blue;">Boolean</span>
<span style="color: blue;"> Try</span>
<span style="color: green;"> 'Abro/Creo mutex con nombre único</span>
_mutex = <span style="color: blue;">New</span> System.Threading.Mutex(<span style="color: blue;">False</span>, mutexName, newMutexCreated)
<span style="color: blue;"> If</span> <span style="color: blue;">Not</span> newMutexCreated <span style="color: blue;">Then</span>
_mutex.Close()
<span style="color: blue;"> End</span> <span style="color: blue;">If</span>
<span style="color: blue;"> Return</span> newMutexCreated
<span style="color: blue;"> Catch</span> ex <span style="color: blue;">As</span> Exception
<span style="color: blue;"> Return</span> <span style="color: blue;">False</span>
<span style="color: blue;"> End</span> <span style="color: blue;">Try</span>
<span style="color: blue;"> End</span> <span style="color: blue;">Function</span>
<span style="color: blue;">End</span> <span style="color: blue;">Class</span></pre></div><br />
<br />
La forma de utilizar esta clase es:<br />
<br />
<div style="background-color: lightgrey; color: black;"><span style="font-size: 78%;"></span><br />
<pre><span style="color: green;">'Sólo se corre la aplicación si no se rebasa el límite, en este caso, de 3 instancias</span>
<span style="color: blue;">Sub</span> main()
<span style="color: blue;"> If</span> <span style="color: blue;">Not</span> InstanciaPrevia.RebasaLimite(eTipo.<span style="color: blue;">GLOBAL</span>, 3) <span style="color: blue;">Then</span>
Application.Run(Form1)
<span style="color: blue;"> Else</span>
MessageBox.Show(<span style="color: firebrick;">"Se pasó del límite"</span>)
Application.<span style="color: blue;">Exit</span>()
<span style="color: blue;"> End</span> <span style="color: blue;">If</span>
<span style="color: blue;">End</span> <span style="color: blue;">Sub</span></pre></div><br />
<span style="font-size: 130%;">Puedes bajar este ejemplo </span><a href="http://www.mediafire.com/?q917otc2yal416t"><span style="font-size: 130%;">aquí</span></a><span style="font-size: 130%;"><br />
</span><br />
<br />
<br />
SuerteAnonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-83854709536373398332009-03-09T17:34:00.000-07:002009-03-09T18:19:56.403-07:00Juego de la vida de Conway con Small BasicSmall Basic es una version reducida del Basic .NET de Microsoft, está enfocado a entornos educativos y su meta fundamental es convertir la programación en algo divertido y sencillo.<br /><br />Desde <a href="http://msdn.microsoft.com/en-us/devlabs/cc950524.aspx">aquí </a>se puede bajar el Small Basic totalmente gratis.<br /><br />La interfaz es muy intuitiva:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkERcpe6EbzjYvhOhDxQI_zDWD0seWy15gWZFf7YHFYIcddEKxVikdVRshegZxMO-WOzGMUCMj_gmS4caLaC8AB-Rkb5mAw8lAZRbz4sT3t4udhNmR_2hC5OIs3tJE-uKEUV0gvpYN45R3/s1600-h/smallbasicIDE_thumb_573F030B.jpg"><img id="BLOGGER_PHOTO_ID_5311354975203790834" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 259px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkERcpe6EbzjYvhOhDxQI_zDWD0seWy15gWZFf7YHFYIcddEKxVikdVRshegZxMO-WOzGMUCMj_gmS4caLaC8AB-Rkb5mAw8lAZRbz4sT3t4udhNmR_2hC5OIs3tJE-uKEUV0gvpYN45R3/s400/smallbasicIDE_thumb_573F030B.jpg" border="0" /></a><br /><br />A continuacion se plasma el código para SmallBasic de la simulación del <a href="http://es.wikipedia.org/wiki/Juego_de_la_vida">juego de la vida de Conway</a>:<br /><br /><blockquote><pre><span style="color:#008000;">'ThePirat 2009</span><br />GraphicsWindow.PenColor = <span style="color:#b22222;">"Red"</span><br />GraphicsWindow.BrushColor = <span style="color:#b22222;">"Blue"</span><br />GraphicsWindow.BackgroundColor=<span style="color:#b22222;">"white"</span><br />GraphicsWindow.MouseDown = OnMouseDown<br />GraphicsWindow.KeyDown = OnKeyDown<br />GraphicsWindow.Show()<br /><br />SIZE = 30<br />Randomize()<br /><br />RunLoop:<br /> Draw()<br /> Paso()<br /> Program.Delay(1)<br /><span style="color:#0000ff;">Goto</span> RunLoop<br /><br /><span style="color:#0000ff;">Sub</span> Randomize<br /> <span style="color:#0000ff;">For</span> i = 0 <span style="color:#0000ff;">To</span> (SIZE * SIZE - 1)<br /> <span style="color:#0000ff;">If</span> (Math.GetRandomNumber(5) > 3) <span style="color:#0000ff;">Then</span><br /> Array.SetValue(<span style="color:#b22222;">"arr"</span>, i, 1)<br /> <span style="color:#0000ff;">Else</span><br /> Array.SetValue(<span style="color:#b22222;">"arr"</span>, i, 0)<br /> <span style="color:#0000ff;">EndIf</span><br /> Endfor<br />EndSub<br /><br /><span style="color:#0000ff;">Sub</span> Draw<br /> GraphicsWindow.Clear()<br /> w = GraphicsWindow.Width<br /> h = GraphicsWindow.Height<br /> <span style="color:#0000ff;">For</span> i = 0 <span style="color:#0000ff;">To</span> (SIZE * SIZE - 1)<br /> val = Array.GetValue(<span style="color:#b22222;">"arr"</span>, i)<br /> <span style="color:#0000ff;">If</span> (val = 1) <span style="color:#0000ff;">Then</span><br /> GraphicsWindow.FillEllipse(w / SIZE * Math.Remainder(i+1, SIZE), h / SIZE * (Math.Floor(i / SIZE)), w / SIZE, h / SIZE)<br /> <span style="color:#008000;">'GraphicsWindow.SetPixel(Math.Remainder(i+1, SIZE), Math.Floor(i / SIZE), "Blue")</span><br /> <span style="color:#0000ff;">EndIf</span><br /> EndFor<br />EndSub<br /><br /><br /><span style="color:#0000ff;">Sub</span> Paso<br /> <span style="color:#008000;">'Col = 1 if first column, Col = 2 if last column, Col = 0 otherwise</span><br /> <span style="color:#008000;">'Row = 1 if first row, Row = 2 if last row, Row = 0 otherwise</span><br /> <span style="color:#0000ff;">For</span> i = 0 <span style="color:#0000ff;">To</span> (SIZE * SIZE - 1)<br /> Alive = 0<br /> COL = 0<br /> ROW = 0<br /> <span style="color:#0000ff;">If</span> (Math.Remainder(i, SIZE) = 0) <span style="color:#0000ff;">Then</span><br /> COL = 1 <span style="color:#008000;">'First col</span><br /> <span style="color:#0000ff;">Endif</span><br /> <span style="color:#0000ff;">If</span> (Math.Remainder(i + 1, SIZE) = 0) <span style="color:#0000ff;">Then</span><br /> COL = 2 <span style="color:#008000;">'Last col</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (i<SIZE) <span style="color:#0000ff;">Then</span><br /> ROW = 1 <span style="color:#008000;">'First row</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (i>=(SIZE*SIZE-SIZE)) <span style="color:#0000ff;">Then</span><br /> ROW = 2 <span style="color:#008000;">'Last row</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <br /> <span style="color:#0000ff;">If</span> (COL <> 1 <span style="color:#0000ff;">And</span> ROW <> 1) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'not 1st row, not 1st col</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i - (SIZE + 1)) <span style="color:#008000;">'Up-Left</span><br /> <span style="color:#0000ff;">Endif</span><br /> <span style="color:#0000ff;">If</span> (ROW <> 1) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'Not 1st row</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i - SIZE) <span style="color:#008000;">'Up</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (COL <> 2 <span style="color:#0000ff;">And</span> ROW <> 1) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'Not mast col, not 1st row</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i - (SIZE - 1)) <span style="color:#008000;">'Up-Right</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (COL <> 1) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'Not 1st col</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i - 1) <span style="color:#008000;">'Left</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (COL <> 2) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'Not last col</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i + 1) <span style="color:#008000;">'Right</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (COL <> 1 <span style="color:#0000ff;">And</span> ROW <> 2) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'Not 1st col, not last row</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i + (SIZE - 1)) <span style="color:#008000;">'Down-Left</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (ROW <> 2) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'Not last row</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i + SIZE) <span style="color:#008000;">'Down</span><br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (COL <> 2 <span style="color:#0000ff;">And</span> ROW <> 2) <span style="color:#0000ff;">Then</span> <span style="color:#008000;">'Not last col, not last row</span><br /> Alive = Alive + Array.GetValue(<span style="color:#b22222;">"arr"</span>, i + (SIZE + 1)) <span style="color:#008000;">'Down-Right</span><br /> <span style="color:#0000ff;">EndIf</span><br /><br /> actual = Array.GetValue(<span style="color:#b22222;">"arr"</span>, i)<br /> newValue = actual<br /> <span style="color:#0000ff;">If</span> (actual = 0 <span style="color:#0000ff;">And</span> Alive = 3) <span style="color:#0000ff;">Then</span><br /> newValue = 1<br /> <span style="color:#0000ff;">EndIf</span><br /> <span style="color:#0000ff;">If</span> (actual = 1 <span style="color:#0000ff;">And</span> Alive <> 2 <span style="color:#0000ff;">And</span> Alive <> 3) <span style="color:#0000ff;">Then</span><br /> newValue = 0<br /> <span style="color:#0000ff;">EndIf</span><br /> <br /> Array.SetValue(<span style="color:#b22222;">"arrTmp"</span>, i, newValue) <br /> Endfor<br /> <br /> <span style="color:#008000;">'Copy "arrTmp" into "arr"</span><br /> <span style="color:#0000ff;">For</span> k = 0 <span style="color:#0000ff;">To</span> (SIZE * SIZE - 1)<br /> Array.SetValue(<span style="color:#b22222;">"arr"</span>, k, Array.GetValue(<span style="color:#b22222;">"arrTmp"</span>, k))<br /> EndFor<br />EndSub<br /><br /><span style="color:#0000ff;">Sub</span> OnMouseDown<br /> Randomize()<br />EndSub<br /><span style="color:#0000ff;">Sub</span> OnKeyDown<br /> Randomize()<br />EndSub</pre></blockquote><br /><br />Aquí se muestra la captura del programa corriendo:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5-A0X4oeku8n-cewdQKzhPOsIK1KgN0w96oplLDP_KpEfHhQH8lwForwtginUGSp7YnChNp3UYH83WPOkq2-btBKuhnOIzZPXUQuNAb6ZrcIPmzGChG7dAtbNDEhNi87MLKhEW3wqNs34/s1600-h/conway1.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 314px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5-A0X4oeku8n-cewdQKzhPOsIK1KgN0w96oplLDP_KpEfHhQH8lwForwtginUGSp7YnChNp3UYH83WPOkq2-btBKuhnOIzZPXUQuNAb6ZrcIPmzGChG7dAtbNDEhNi87MLKhEW3wqNs34/s400/conway1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5311361963668684866" /></a><br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuy3vUDxKvDg6RwIsIpRORu0jfCEPf3o6rFgNFphZ3R9SpdFOK_-66SkqZ759A-UovtYFqj2jm-DPal_YXuRRtiGkfl4a9e4UUNp-sFXdvc2eMkQKdWfgcMe6pJCVenuSQzyzcFxlzgAxC/s1600-h/conway2.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 316px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuy3vUDxKvDg6RwIsIpRORu0jfCEPf3o6rFgNFphZ3R9SpdFOK_-66SkqZ759A-UovtYFqj2jm-DPal_YXuRRtiGkfl4a9e4UUNp-sFXdvc2eMkQKdWfgcMe6pJCVenuSQzyzcFxlzgAxC/s400/conway2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5311362595919131442" /></a><br /><br />Esta versión es muy simple y sólo permite configurar el tamaño de la grilla cambiando el valor de la variable SIZE.<br /><br />Existen versiones más completas del juego de la vida para SmallBasic en<a href="http://social.msdn.microsoft.com/Forums/en-US/smallbasic/thread/eaacf826-9d12-4e3c-aa10-1b2788f160a6"> este foro</a><br /><br />Suerte !!!Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-55059729153258748272009-02-04T16:22:00.000-08:002009-03-18T14:21:49.182-07:00Red Gate Reflector para Crackear a Red Gate SQL Compare<strong>Cómo usar el "Red Gate .NET reflector" para crackear al "Red Gate SQL Compare 6" e</strong><strong>n 10 pasos </strong><br /><strong><br /><br /></strong><strong></strong>Requisitos:<br />Instalar el .NET Reflector (que ahora es de Red Gate, pero originalmente de Lutz Roeder) de <a href="http://www.red-gate.com/products/reflector/">http://www.red-gate.com/products/reflector/</a><br /><br />Instalar el Add-In "Reflexil" para el .NET Reflector de <a href="http://sourceforge.net/project/showfiles.php?group_id=200895">http://sourceforge.net/project/showfiles.php?group_id=200895</a><br /><br />Instalar la versión Trial de Red Gate SQL Compare 6 de <a href="https://www.red-gate.com/dynamic/downloads/downloadform.aspx?download=sqltoolbelt">https://www.red-gate.com/dynamic/downloads/downloadform.aspx?download=sqltoolbelt</a><br /><br />1) instalar el <em>.NET Reflector</em> y su Add-In <em>Reflexil</em> en la misma carpeta y luego desde el <em>Reflector</em> agregar el Add-In desde el menú <em>View, Add-Ins</em><br /><br /><br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvwo978VxmovDD-4E0kmM47iHW3DzE74h4mJMTQsiznnWcSE8S920CxL77Sx5oIzvNlQX0mC_eGb2aGt4QLDzmfeDm7pcu_TvhvjOMuoXGNXLHL6oskivVcbnZNdyf_DdtAB697fYmgejz/s1600-h/Add-In.JPG"><img id="BLOGGER_PHOTO_ID_5299114484008997682" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 289px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvwo978VxmovDD-4E0kmM47iHW3DzE74h4mJMTQsiznnWcSE8S920CxL77Sx5oIzvNlQX0mC_eGb2aGt4QLDzmfeDm7pcu_TvhvjOMuoXGNXLHL6oskivVcbnZNdyf_DdtAB697fYmgejz/s320/Add-In.JPG" border="0" /></a><br />2) Abrir en el <em>Reflector</em>, la dll del Red Gate SQL Compare 6 que se encarga de evaluar las licencias:<em> C:\Program Files\Red Gate\SQL Compare 6\RedGate.Licensing.Client.dll<br /></em><br /><br />Ahora lo que vamos a hacer es ubicar el método<em> get_Activated</em>, que devuelve <em>True</em> en caso de que el software esté activado<br /><br /><br />3) Navegar en el arbol de la izquierda hasta: <em>RedGate.Licensing.Client, License, Activated, get_Activated()</em>, darle doble click para desemsamblar<br /><br /><br />4) Abrir el Reflexil (<em>Menú Tools, Reflexil</em>)<br /><br /><br />Ahora vamos a modificar el código del método para que devuelva siempre <em>True</em><br /><br />5) Eliminar la segunda línea del código MSIL como se muestra a continuación:<br /><br /><br /><img id="BLOGGER_PHOTO_ID_5299424048407135378" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 133px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZa84L_SBDO6jsxOyJPvw4i03swOsLXVrfUt8waMEv8k5Ef7kxrM5h81TU_tPz5JxpyAXv_ljgPF7ZPLVKMaRJGK6oI5f4leLOBiwm1ZZvhbuRNjxzWOdEV6crtVCAmuAa7fKgCz6BQZpF/s400/msil.jpg" border="0" />6) De las dos instrucciones que quedaron, editar la primera como se muestra a continuación:<br /><br /><img id="BLOGGER_PHOTO_ID_5299424373293546066" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 128px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6QtfZndyjEM5iS2LKFjWepbQJpMnAnjv_JTS0z4ChaZIPBVWgDgp05LTrzhIxB1TzcNxC60EE4fxYkGlaxa4iiDuylEr-k5YNJHoB3CiSGbqAOLjofhE0tmIggw_fnDppxgeazcaXdkMi/s400/msil2.jpg" border="0" />7) Cambiar el código de la instrucción por el código <em>ldc.i4.1</em> y darle <em>Update</em>, como se muestra a continuación:<br /><br /><img id="BLOGGER_PHOTO_ID_5299425106023682242" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 125px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO747FMqWVFXH2odJ9O-fSydwsiv6jXewuXPILJEs1jxAt0_uBZN7uQ4fxZMvc9Zc0BrQBxEY65NWolZaGWH4VVvfHyqN6QXR4W0zlNl69IiNETAj5RXo8iVoxk6lkPExRuF0hfzaoQ4_0/s400/msil3.jpg" border="0" /><br />Listo... sólo nos falta guardar la DLL modificada, para eso<br /><br /><br />8) Navegar hacia arriba en el arbol de la izquierda hasta el nodo <em>RedGate.Licensing.Client.dll</em>, el Add-In del <em>Reflexil</em> cambiará su interfaz por una que tiene dos botones. Darle click al botón <em>Save As...</em> Como se muestra a continuación:<br /><br /><img id="BLOGGER_PHOTO_ID_5299426155296691314" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 118px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiNUSsJ-1-5gJ4evPPTsVA64JzA6CPP2P43xfpMYnBoa6KDl1EI6AwZIpLXviCPUgSHl-62H-u7imZ4wZhyphenhyphenWj_MbvKql2C5ldV21guzbO3eYc8NqBHaoqg9cvPZU8lw0whvJBnhsuEswO3/s400/saveas.jpg" border="0" />9) Por defecto guardará la dll con nombre <em>RedGate.Licensing.Client.Patched.dll</em> por lo cual habría que reemplazar la librería original <em>RedGate.Licensing.Client.Dll</em> y cambiarla por ésta.<br /><br /><br />10) Al guardar aparecerá un mensaje, se le puede dar en <em>Cancel and Keep it Delay Signed</em> y no habrá problemas.<br /><br /><br />Suerte...<br /><br />El presente artículo sólo tiene fines didácticos, si quieres seguir utilizando el software de Red Gate, debes comprar la versión full luego de pasados los 14 días...<br /><pre></pre>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-5209240899699584212009-01-15T16:21:00.000-08:002009-02-11T10:12:46.983-08:00Aplicación suicida en VB.NET - Programa que se elimina a sí mismoHe aquí una curiosa forma de hacer que un ejecutable se elimine a sí mismo:<br /><br /><pre><span style="color:#0000ff;">Module</span> Module1<br /> <span style="color:#0000ff;">Sub</span> Main()<br /> Suicide()<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> <span style="color:#0000ff;">Sub</span> Suicide()<br /> <span style="color:#0000ff;">Dim</span> EXEName <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span> = VB6.GetEXEName() & <span style="color:#b22222;">".exe"</span><br /> MakeBat(EXEName)<br /> <span style="color:#0000ff;">Dim</span> Info <span style="color:#0000ff;">As</span> ProcessStartInfo = <span style="color:#0000ff;">New</span> ProcessStartInfo()<br /> Info.Arguments = <span style="color:#b22222;">"/C deleter.bat"</span><br /> Info.WindowStyle = ProcessWindowStyle.Hidden<br /> Info.CreateNoWindow = <span style="color:#0000ff;">True</span><br /> Info.FileName = <span style="color:#b22222;">"cmd.exe"</span><br /> Process.Start(Info)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> <span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Sub</span> MakeBat(<span style="color:#0000ff;">ByVal</span> EXEName <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span>)<br /> <span style="color:#0000ff;">Dim</span> sb <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">New</span> System.Text.StringBuilder<br /> sb.AppendLine(<span style="color:#b22222;">"@echo off"</span>)<br /> sb.AppendLine(<span style="color:#b22222;">":loopb"</span>)<br /> sb.AppendLine(<span style="color:#b22222;">"del """</span> & EXEName & ""<span style="color:#b22222;">" > nul"</span>)<br /> sb.AppendLine(<span style="color:#b22222;">"IF EXIST """</span> & EXEName & ""<span style="color:#b22222;">" goto loopb"</span>)<br /> sb.AppendLine(<span style="color:#b22222;">"del deleter.bat"</span>)<br /> <span style="color:#0000ff;">My</span>.Computer.FileSystem.WriteAllText(<span style="color:#b22222;">"deleter.bat"</span>, sb.ToString(), <span style="color:#0000ff;">False</span>)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /><span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Module</span></pre><br /><br />Se debe agregar una referencia y el Imports a Microsoft.VisualBasic.Compatibility<br /><pre></pre>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-56235049977024527702008-12-01T15:21:00.000-08:002009-02-06T09:43:10.715-08:00Convertir un campo público a propiedad Visual Studio - VB y C#<strong>Cómo hacer para convertir automáticamente un campo (variable) a una propiedad pública y utilizarlo con una combinación de teclas en el Visual Studio 2008.</strong><br /><br />La idea es crear una macro que se encargue de hacer la conversión de la línea actual de código donde estemos parados y poder ejecutar esta macro con alguna combinación de teclas.<br /><br />Por ejemplo, queremos convertir esta línea:<br /><pre><span style="color: #0000FF">Public</span> id <span style="color: #0000FF">As</span> <span style="color: #0000FF">Integer</span></pre><br />En esto:<br /><pre><span style="color:#0000ff;">Private</span> _id <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span><br /><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Property</span> id() <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span><br /> <span style="color:#0000ff;">Get</span><br /> <span style="color:#0000ff;">Return</span> _id<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> <span style="color:#0000ff;">Set</span>(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span>)<br /> _id = value<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Set</span><br /><span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span></pre>NOTA: En Visual Studio 2010 será mucho más simple la declaración de propiedades en VB, pareciéndose más a la declaración en C#<br /><br />Lo primero que se necesita es abrir el explorador de macros (Menú View, Other Windows, Macro Explorer) o bien con ALT+F8.<br />En la nueva ventana, hacer click derecho en MyMacros y seleccionar "New Module", ponerle como nombre <em>thepirat</em>, y nuevamente click derecho (ahora sobre el nuevo módulo recién creado) y seleccionar "New Macro".<br />A continuación aparecerá el editor de macros y estaremos situados dentro de un método que seguramente se llama Sub Macro1() adentro del módulo llamado <em>thepirat</em>.<br /><br />Adentro de este módulo, copiar y reemplazar TODO el código por el siguiente código <pre> </pre><br /><pre><span style="color: #008000">'The-Pirat 2008</span><br /><span style="color: #0000FF">Imports</span> System<br /><span style="color: #0000FF">Imports</span> EnvDTE<br /><span style="color: #0000FF">Imports</span> EnvDTE80<br /><span style="color: #0000FF">Imports</span> EnvDTE90<br /><span style="color: #0000FF">Imports</span> System.Diagnostics<br /><span style="color: #0000FF">Imports</span> System.Text.RegularExpressions<br /><br /><span style="color: #008000">'http://msdn.microsoft.com/en-us/library/envdte.textselection_members.aspx</span><br /><br /><span style="color: #0000FF">Public</span> <span style="color: #0000FF">Module</span> thepirat<br /> <span style="color: #008000">'Declaro la expresión regular</span><br /> <span style="color: #0000FF">Private</span> <span style="color: #0000FF">Const</span> REGEX_Declaracion_VB <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span> = _<br /> <span style="color: #B22222">"(public|private|dim)\s+(?'var'\w+)\s+as\s+(?'tipo'.*)"</span><br /> <span style="color: #0000FF">Private</span> <span style="color: #0000FF">Const</span> REGEX_Declaracion_CSHARP <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span> = _<br /> <span style="color: #B22222">"(public\s|private\s|internal\s)?(?'tipo'.+)\s+(?'var'\w+)\s*;"</span><br /><br /> <span style="color: #008000">''' <summary></span><br /> <span style="color: #008000">''' Convierte un campo en propiedad pública.</span><br /> <span style="color: #008000">''' Acepta la forma: Dim variable as tipo, public v as t, private v as t</span><br /> <span style="color: #008000">''' </summary></span><br /> <span style="color: #008000">''' <remarks></remarks></span><br /> <span style="color: #0000FF">Public</span> <span style="color: #0000FF">Sub</span> campo2prop()<br /> <span style="color: #008000">'Creo un punto de UNDO</span><br /> DTE.UndoContext.Open(<span style="color: #B22222">"UndoCampoPropiedad"</span>)<br /> <span style="color: #0000FF">Try</span><br /> <span style="color: #008000">'Obtengo el documento activo </span><br /> <span style="color: #0000FF">Dim</span> doc = <span style="color: #0000FF">CType</span>(DTE.ActiveDocument, EnvDTE.Document)<br /> <span style="color: #008000">'Obtengo la selección del documento activo</span><br /> <span style="color: #0000FF">Dim</span> ts <span style="color: #0000FF">As</span> TextSelection = doc.Selection<br /> <span style="color: #008000">'Selecciono la línea completa</span><br /> ts.SelectLine()<br /> <span style="color: #008000">'Determino si es VB o C#</span><br /> <span style="color: #0000FF">Dim</span> bVB <span style="color: #0000FF">As</span> <span style="color: #0000FF">Boolean</span> = EsVisualBasic(doc.Name)<br /> <span style="color: #008000">'Obtengo el texto de la selección (la línea)</span><br /> <span style="color: #0000FF">Dim</span> sLinea <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span> = ts.Text.Trim()<br /> <span style="color: #008000">'Obtengo el nombre de la variable y su tipo</span><br /> <span style="color: #0000FF">Dim</span> sVar <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span> = "", sTipo <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span> = ""<br /> ObtenerVariableYtipo(bVB, sLinea, sVar, sTipo)<br /> <span style="color: #008000">'Si fue exitoso, imprimo la propiedad</span><br /> ts.Insert(DevolverPropiedad(bVB, sVar, sTipo))<br /> <span style="color: #0000FF">Catch</span> ex <span style="color: #0000FF">As</span> Exception<br /> MsgBox(ex.Message)<br /> <span style="color: #0000FF">Finally</span><br /> <span style="color: #008000">'Cierro el punto de UNDO</span><br /> DTE.UndoContext.Close()<br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">Try</span><br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">Sub</span><br /><br /> <span style="color: #008000">'Determina si es VB o C#</span><br /> <span style="color: #0000FF">Private</span> <span style="color: #0000FF">Function</span> EsVisualBasic(<span style="color: #0000FF">ByVal</span> nombre <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span>) <span style="color: #0000FF">As</span> <span style="color: #0000FF">Boolean</span><br /> <span style="color: #0000FF">If</span> (nombre.EndsWith(<span style="color: #B22222">".cs"</span>) <span style="color: #0000FF">Or</span> nombre.EndsWith(<span style="color: #B22222">".cpp"</span>) <span style="color: #0000FF">Or</span> nombre.EndsWith(<span style="color: #B22222">".h"</span>) <span style="color: #0000FF">Or</span> nombre.EndsWith(<span style="color: #B22222">".idl"</span>) <span style="color: #0000FF">Or</span> nombre.EndsWith(<span style="color: #B22222">".jsl"</span>)) <span style="color: #0000FF">Then</span><br /> <span style="color: #0000FF">Return</span> <span style="color: #0000FF">False</span><br /> <span style="color: #0000FF">ElseIf</span> (nombre.EndsWith(<span style="color: #B22222">".vb"</span>)) <span style="color: #0000FF">Then</span><br /> <span style="color: #0000FF">Return</span> <span style="color: #0000FF">True</span><br /> <span style="color: #0000FF">Else</span><br /> <span style="color: #0000FF">Throw</span> <span style="color: #0000FF">New</span> Exception(<span style="color: #B22222">"Tipo de archivo irreconocible"</span>)<br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">If</span><br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">Function</span><br /><br /> <span style="color: #008000">'Devuelve el nombre de la variable y el nombre del tipo de la variable a partir de la línea de declaración</span><br /> <span style="color: #0000FF">Private</span> <span style="color: #0000FF">Sub</span> ObtenerVariableYtipo(<span style="color: #0000FF">ByVal</span> VisualBasic <span style="color: #0000FF">As</span> <span style="color: #0000FF">Boolean</span>, <span style="color: #0000FF">ByVal</span> Linea <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span>, _<br /> <span style="color: #0000FF">ByRef</span> <span style="color: #0000FF">var</span> <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span>, <span style="color: #0000FF">ByRef</span> tipo <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span>)<br /> <span style="color: #0000FF">var</span> = ""<br /> tipo = ""<br /> <span style="color: #008000">'Obtengo el nombre de la variable y su tipo</span><br /> <span style="color: #0000FF">Dim</span> mc = Regex.Matches(Linea.Trim, <span style="color: #0000FF">If</span>(VisualBasic, REGEX_Declaracion_VB, REGEX_Declaracion_CSHARP), _<br /> RegexOptions.IgnoreCase <span style="color: #0000FF">Or</span> RegexOptions.Singleline)<br /><br /> <span style="color: #0000FF">If</span> mc.Count = 0 <span style="color: #0000FF">Then</span><br /> <span style="color: #0000FF">Throw</span> <span style="color: #0000FF">New</span> Exception(<span style="color: #B22222">"La línea actual no es la declaración de una variable"</span>)<br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">If</span><br /><br /> <span style="color: #0000FF">For</span> <span style="color: #0000FF">Each</span> m <span style="color: #0000FF">As</span> Match <span style="color: #0000FF">In</span> mc<br /> <span style="color: #0000FF">var</span> = m.Groups(<span style="color: #B22222">"var"</span>).ToString<br /> tipo = m.Groups(<span style="color: #B22222">"tipo"</span>).ToString<br /> <span style="color: #0000FF">Next</span><br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">Sub</span><br /><br /> <span style="color: #008000">'Devuelve el texto convertido a propiedad</span><br /> <span style="color: #0000FF">Private</span> <span style="color: #0000FF">Function</span> DevolverPropiedad(<span style="color: #0000FF">ByVal</span> VisualBasic <span style="color: #0000FF">As</span> <span style="color: #0000FF">Boolean</span>, _<br /> <span style="color: #0000FF">ByRef</span> <span style="color: #0000FF">var</span> <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span>, <span style="color: #0000FF">ByRef</span> tipo <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span>) <span style="color: #0000FF">As</span> <span style="color: #0000FF">String</span><br /> <span style="color: #0000FF">If</span> VisualBasic <span style="color: #0000FF">Then</span><br /> <span style="color: #0000FF">Return</span> (<span style="color: #0000FF">String</span>.Format( _<br /> <span style="color: #B22222">"Private _{1} As {2}{3}"</span> & _<br /> <span style="color: #B22222">"Public Property {1}() As {2}{3}"</span> & _<br /> <span style="color: #B22222">"{0}Get{3}"</span> & _<br /> <span style="color: #B22222">"{0}{0}Return _{1}{3}"</span> & _<br /> <span style="color: #B22222">"{0}End Get{3}"</span> & _<br /> <span style="color: #B22222">"{0}Set(ByVal value As {2}){3}"</span> & _<br /> <span style="color: #B22222">"{0}{0}_{1} = value{3}"</span> & _<br /> <span style="color: #B22222">"{0}End Set{3}"</span> & _<br /> <span style="color: #B22222">"End Property{3}"</span>, _<br /> vbTab, <span style="color: #0000FF">var</span>, tipo, vbCrLf))<br /> <span style="color: #0000FF">Else</span><br /> <span style="color: #0000FF">Return</span> (<span style="color: #0000FF">String</span>.Format( _<br /> <span style="color: #B22222">"{0}{0}public {1} {2} {{ get; set; }}"</span>, vbTab, tipo, <span style="color: #0000FF">var</span>))<br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">If</span><br /> <span style="color: #0000FF">End</span> <span style="color: #0000FF">Function</span><br /><br /><span style="color: #0000FF">End</span> <span style="color: #0000FF">Module</span></pre>A continuación guardar y cerrar la ventana del editor de macros.<br /><br />Ahora ya existe el método <em>thepirat.campo2prop </em>que a partir de la línea actual del editor del Visual Studio, convierte <em>la declaración de un campo</em> a una <em>declaración de una propiedad </em>con el mismo nombre.<br /><br /><br /><br />Sólo falta vincular un acceso directo para poder utilizar la macro con una combinación de teclas.<br /><br />Para esto, ir al menú <em>Tools</em>, <em>Customize </em>y luego click en el botón <em>Keyboard... </em>Buscar el método <em>campo2prop </em>como se muestra a continuación:<br /><br /><img id="BLOGGER_PHOTO_ID_5299435717098968450" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 186px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipwFSNjg6VkaSbNdBS_qYvzxyYj_NSOZxzlPdaq8QEmqerFaozU70hNYs_C7oLnXaMg1BFS8mEP4WDL8RckvcoDgZSajNTaP3s8Drne4p0mKHqf_Jgsiwi-q_-DGpgSNaNmjBvvUv0h9jO/s320/1.jpg" border="0" /><br />Presionar la combinación de teclas deseada en la parte indicada y luego darle click en <em>Assign</em><br /><br />Listo! Ahora desde cualquier ventana del editor de Visual Studio, se puede hacer esto:<br /><br /><p></p>Me paro en la línea de la declaración de un campo:<br /><br /><p><img id="BLOGGER_PHOTO_ID_5299436810658081906" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 209px; CURSOR: hand; HEIGHT: 93px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOD_-9s8T1ZXkBNk9IvXpV7ceRQv-NX_6v4QQTniDA9_AgnhYvz6ufIwWfSdpMd1r5OXDZo22qFMPE2H7thBG1ucK4UDG6505Hbcx3T5FOdxlVsWt5-A41xZOj7OkNhnLp5wQGQLfsrOT4/s320/2.jpg" border="0" /><br />Presiono mi combinación de teclas y obtengo:</p><p><br /><img id="BLOGGER_PHOTO_ID_5299437007293358498" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 288px; CURSOR: hand; HEIGHT: 207px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi13oHV_-sJ_pFzXqPs_xhXjvXWLt7Qx4tZytfqgTyJnmIjQ1eRXUj1TJyHlXJOITWcd3kh_xBJDvw5Q_JWTTh78ftDAT4ZOxhydK3N_yKOB_tl4AGBtIs7lNRFplupkcIp97a2udDHNtc2/s320/3.jpg" border="0" /><br /></p>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-24191583113830221502008-10-20T15:00:00.001-07:002009-02-05T13:37:02.776-08:00Cómo sugerir texto a partir de lo capturado, al estilo de Google en VB.NET<div>Esta función toma como parámetro un texto, por ejemplo "isaac new" y devuelve una lista con posibles coincidencias, por ejemplo "Isaac Newell" e "Isaac Newton", etc...<br /><br />Util para sugerir texto en búsquedas. </div><br /><div></div><img id="BLOGGER_PHOTO_ID_5299430300230629810" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 140px; CURSOR: hand; HEIGHT: 68px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg0SRtNb-v0VhPkNSZX_l-TJxTro6iNa7dHwhebQHk9wkluwv4KJA6diPW-v1alaeRTmuogTy90R0nnZL6mGkkeD6fnqgkVFl9-XZoD62j2Kk-vN3pf_zlgsJMPeEOQAepaiHLpbvD-0uB/s400/Dibujo.jpg" border="0" /> <div><br />Aquí está el código para VB.NET:<br /></div><pre><span style="color:#0000ff;">Imports</span> System.Xml<br /><br /><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> google<br /><br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Function</span> getList(<span style="color:#0000ff;">ByVal</span> prefixText <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span>) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span>()<br /><br /> <span style="color:#0000ff;">Dim</span> doc <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">New</span> XmlDocument()<br /><br /> <span style="color:#0000ff;">Dim</span> suggArList <span style="color:#0000ff;">As</span> List(<span style="color:#0000ff;">Of</span> <span style="color:#0000ff;">String</span>) = <span style="color:#0000ff;">New</span> List(<span style="color:#0000ff;">Of</span> <span style="color:#0000ff;">String</span>)()<br /><br /> <span style="color:#0000ff;">Dim</span> url <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span> = <span style="color:#b22222;">"http://google.com/complete/search?output=toolbar&q="</span> & prefixText<br /><br /> doc.Load(url)<br /><br /> <span style="color:#0000ff;">For</span> <span style="color:#0000ff;">Each</span> node <span style="color:#0000ff;">As</span> XmlNode <span style="color:#0000ff;">In</span> doc.SelectNodes(<span style="color:#b22222;">"//CompleteSuggestion"</span>)<br /><br /> <span style="color:#0000ff;">Dim</span> <span style="color:#0000ff;">value</span> <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span> = node.SelectSingleNode(<span style="color:#b22222;">"suggestion/@data"</span>).InnerText<br /><br /> suggArList.<span style="color:#0000ff;">Add</span>(<span style="color:#0000ff;">value</span>)<br /><br /> <span style="color:#0000ff;">Next</span><br /><br /> <span style="color:#0000ff;">Return</span> suggArList.ToArray()<br /><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /><br /><span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span></pre>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-59675744985126299932008-08-05T15:48:00.000-07:002009-02-11T10:14:18.350-08:00Cómo cambiar el comportamiento por defecto al pulsar CTRL+ENTER en el Internet ExplorerAl pulsar CTRL+ENTER en la barra de direcciones del IE, éste automáticamente completa el texto escrito con el prefijo "http://www." y el postfijo ".com".<br /><br />Por ejemplo si ponemos yahoo y luego CTRL+ENTER, el IE irá a la página "http://www.yahoo.com" automáticamente.<br /><br />Si se requiere cambiar este comportamiento, por ejemplo, que el postfijo sea ".com.ar" en vez de ".com", hay que crear una carpeta y una clave en el registro de windows.<br /><br />Desde el regedit.exe acceder a la ruta<br />"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar"<br />Ahi dentro crear una carpeta que se llame "QuickComplete"<br />Y dentro de esa carpeta crear una clave de tipo string (REG_SZ) con nombre "QuickComplete", cuyo contenido sea, por ejemplo:<br />"http://www.%s.com.ar" (sin las comillas)<br /><br />En definitiva, la ruta completa de la clave a agregar es:<br />"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar\QuickComplete\QuickComplete"<br /><br />Notar que el wildcard %s será reemplazado con el texto que contenga la barra de exploración<br /><pre></pre>Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0tag:blogger.com,1999:blog-8699577164878004669.post-47859256498933507542008-07-14T12:24:00.000-07:002008-10-05T17:15:12.074-07:00Efectuar un CVS update desatentido disparado desde SQL Server<strong>El requerimiento:</strong><br />Hacer un update de un repositorio de CVS utilizando el protocolo pserver con usuario y constreñas conocidas.<br />Es necesario que el update se pueda efectuar "desatendidamente" desde un procedimiento de SQL Server 2000/2005/2008<br /><br /><strong>El problema:</strong><br />Al hacer el login al CVS, la constraseña del pserver es guardada en algún lugar del registro asociado con la sesión de usuario, así que si se dispara el update desde otra sesión o desde otro usuario (por ejemplo desde un job de SQL Server) surge el problema de que la contraseña no queda guardada y el update no puede ser efectuado.<br />Aunque se cree la credencial y el proxy adecuado en SQL, el problema sigue existiendo.<br /><br /><strong>La solución:</strong><br />Efectuar el checkout del módulo localmente.<br />Crear un archivo de texto plano que sólo contenga la contraseña del usuario del CVS y un archivo .bat que haga el login y el update.<br /><br />El contenido de UpdateCVS.bat es el siguiente:<br /><br /><blockquote><br />:Asigno el PATH a la carpeta que contiene el archivo CVS.exe<br />PATH = C:\Program Files\TortoiseCVS<br /><br />:Voy a la carpeta que tiene el checkout<br />C:<br />CD \repositorio\Carpeta<br /><br />:Seteo la configuracion del CVS<br />SET CVSROOT = :pserver:usuario@cvs.miempresa.com:2401/home/cvs<br /><br />:Intruduzco el password redireccionando el stdin<br />:Es necesario que el password esté en el archivo c:\passw<br />cvs.exe login<BOLD><</BOLD>c:\passw<br /><br />:Disparo el Update<br />cvs.exe -q update -d -P<br /></blockquote><br /><br />Dentro del .bat, el comando CVS Login preguntará la contraseña. Para que ésta sea introducirla automáticamente, se redirecciona el standard input al archivo que contiene la contraseña. Esto se hace con el caracter "<".<br />El archivo passw debe terminar con un retorno (enter).<br /><br />Luego, para ejecutar el .bat desde T-SQL:<br /><blockquote>Exec xp_CMDShell 'UpdateCVS.bat'<br /></blockquote><br />Este exec puede ponerse dentro en un Job para automatizar completamente el proceso.Anonymoushttp://www.blogger.com/profile/05225527023711214192noreply@blogger.com0