<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Laurent Ellerbach : Visual Studio</title><link>http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx</link><description>Tags: Visual Studio</description><dc:language>fr</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Apprendre .NET avec la Saga .NET</title><link>http://blogs.msdn.com/laurelle/archive/2007/10/16/apprendre-net-avec-la-saga-net.aspx</link><pubDate>Tue, 16 Oct 2007 11:41:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5468550</guid><dc:creator>laurelle</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/5468550.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=5468550</wfw:commentRss><description>&lt;p&gt;Mieux que Dalas, la Saga .NET, r&amp;#xE9;alis&amp;#xE9;e par &lt;a href="http://blogs.msdn.com/Pascal/"&gt;Pascal Belaud&lt;/a&gt;, va vous permettre de vous mettre &amp;#xE0; .NET. C&amp;#x2019;est un cursus de cours de 10 &amp;#xE9;pisodes complets avec des vid&amp;#xE9;os, les codes sources associ&amp;#xE9;s et de quoi refaire les exercices.&lt;/p&gt;  &lt;p&gt;Ce que j&amp;#x2019;aime particuli&amp;#xE8;rement chez Pascal, c&amp;#x2019;est sa p&amp;#xE9;dagogie, les explications qu&amp;#x2019;il donne sont toujours claires et les exemples parlent bien. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/pascal/WindowsLiveWriter/Lasaga.NETestenfinlance_11B96/image_2.png"&gt;&lt;img height="133" alt="image" src="http://blogs.msdn.com/blogfiles/pascal/WindowsLiveWriter/Lasaga.NETestenfinlance_11B96/image_thumb.png" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;La s&amp;#xE9;rie sera compl&amp;#xE9;t&amp;#xE9;e par d&amp;#x2019;autres &amp;#xE9;pisodes si nous en avons la demande. Aussi, n&amp;#x2019;h&amp;#xE9;sitez pas &amp;#xE0; r&amp;#xE9;agir en &lt;a href="mailto:laurelle@microsoft.com"&gt;m&amp;#x2019;envoyant un mail&lt;/a&gt; ou dans les commentaires.&lt;/p&gt;  &lt;p&gt;Ca se passe ici : &lt;a href="http://www.microsoft.com/france/vision/saga-dot-net/"&gt;http://www.microsoft.com/france/vision/saga-dot-net/&lt;/a&gt;&lt;/p&gt; &lt;a class="techtag" href="http://technorati.com/tag/.NET" rel="tag"&gt;.NET&lt;/a&gt; &lt;a class="techtag" href="http://technorati.com/tag/Saga" rel="tag"&gt;Saga&lt;/a&gt; &lt;a class="techtag" href="http://technorati.com/tag/Visual+Studio" rel="tag"&gt;Visual Studio&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5468550" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Etudiants/default.aspx">Etudiants</category></item><item><title>Fréquence MSDN, vous connaissez ?</title><link>http://blogs.msdn.com/laurelle/archive/2007/09/27/fr-quence-msdn-vous-connaissez.aspx</link><pubDate>Thu, 27 Sep 2007 12:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5164112</guid><dc:creator>laurelle</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/5164112.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=5164112</wfw:commentRss><description>&lt;P&gt;C'est un nouveau concept que nous lançons. Une émission de radio diffusée en live avec roundtalbe (donc plutôt de la TV avec vision 360° du plateau) à partir du 10 octobre.&lt;/P&gt;
&lt;P&gt;L'objectif est de pouvoir revenir sur l'actialité des quelques semaines passées, décortiquer des annonces et aussi répondre à vos questions en direct. Vous pourrez en effet poser des questions en direct.&lt;/P&gt;
&lt;P&gt;Nous vous réservons également quelques surprises et un peu de fun :-)&lt;/P&gt;
&lt;P&gt;Nous avons prévu 1 heure pour la première émission. Si le concept plait, alors on remettra ça avec d'autres émissions.&lt;/P&gt;
&lt;P&gt;Pour s'inscrire, c'est là que ça passe : &lt;/P&gt;
&lt;P&gt;&lt;A href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032354930&amp;amp;Culture=fr-FR" mce_href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032354930&amp;amp;Culture=fr-FR"&gt;http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032354930&amp;amp;Culture=fr-FR&lt;/A&gt;&lt;/P&gt;&lt;A class=techtag href="http://technorati.com/tag/MSDN" rel=tag mce_href="http://technorati.com/tag/MSDN"&gt;MSDN&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5164112" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Web+2.0/default.aspx">Web 2.0</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>Cet été j'en ai rien à coder, j'me forme à .NET, Vista, Office, OpenXML...</title><link>http://blogs.msdn.com/laurelle/archive/2007/07/25/cet-t-j-en-ai-rien-coder-j-me-forme-net-vista-office-openxml.aspx</link><pubDate>Wed, 25 Jul 2007 16:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4044495</guid><dc:creator>laurelle</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/4044495.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=4044495</wfw:commentRss><description>&lt;P&gt;Parce que nous savons que l'été est souvent une période plus calme, que nous développeurs, avons besoin de ces temps calmes pour nous former, nous proposons sur MSDN pendant tout l'été une série de dossiers thématiques de formation avec nos coachs préférés. &lt;A class="" href="http://msdn2.microsoft.com/fr-fr/aboutmsdn/bb625975.aspx" mce_href="http://msdn2.microsoft.com/fr-fr/aboutmsdn/bb625975.aspx"&gt;Cet été, j'en ai rien à coder&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Au programme, du .NET, Vista, Office, OpenXML, Visual Studio Team System, Web 2.0... Que du bonheur ! Le tout avec un quizz permettant de valider les principaux points à la fin de chaque devoir de vacances. &lt;/P&gt;
&lt;P&gt;Et surtout, à ne pas manquer à la fin de l'été, un méga quizz qui permettra de valider les compétences de tous les sujets et peut-être de gagner une formation d'une semaine à TechEd, début novembre à Barcelone.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH: 300px; HEIGHT: 312px" height=312 src="http://msdn2.microsoft.com/fr-fr/aboutmsdn/bb625975.image3.png" width=300 mce_src="http://msdn2.microsoft.com/fr-fr/aboutmsdn/bb625975.image3.png"&gt;&lt;/P&gt;
&lt;P&gt;J'espère que cela vous plaira ! N'hésitez pas à laisser un commentaire pour me dire ce que vous en pensez.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;A class=techtag href="http://technorati.com/tag/Formation" rel=tag&gt;Formation&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/j'en+ai+rien+à+coder" rel=tag&gt;j'en+ai+rien+à+coder&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Microsoft" rel=tag&gt;Microsoft&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/.NET" rel=tag&gt;.NET&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Web+2.0" rel=tag&gt;Web+2.0&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/OpenXML" rel=tag&gt;OpenXML&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Vista" rel=tag&gt;Vista&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Visual+Studio" rel=tag&gt;Visual+Studio&lt;/A&gt; &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4044495" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Web+2.0/default.aspx">Web 2.0</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Vista/default.aspx">Vista</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Etudiants/default.aspx">Etudiants</category></item><item><title>Envie de C# ? Trop dur ? Pas de panique, la coach est là !</title><link>http://blogs.msdn.com/laurelle/archive/2007/05/11/envie-de-c-trop-dur-pas-de-panique-la-coach-est-l.aspx</link><pubDate>Fri, 11 May 2007 16:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2546887</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/2546887.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=2546887</wfw:commentRss><description>&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.aspx" mce_href="http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.aspx" ? atomicselection="true"&gt;&lt;IMG title=image style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: 137px; HEIGHT: 240px; BORDER-RIGHT-WIDTH: 0px" height=240 alt=image src="http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.coach_introduction-resaved.jpg" width=137 align=left border=0 mce_src="http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.coach_introduction-resaved.jpg"&gt;&lt;/A&gt;&amp;nbsp;Vous avez entendu parlé de C# ? C'est le langage qui vous fait rêvé ? Vous vous sentez démuni ? Mais vous avez envie de vous lancer ? Et bien, notre délicieuse coach est là pour vous aider.&lt;/P&gt;
&lt;P&gt;De la formation gratuite, guidée, avec des travaux pratiques, le tous super bien fait : &lt;A title=http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.aspx href="http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.aspx" mce_href="http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#355ea0&gt;http://msdn2.microsoft.com/fr-fr/vcsharp/bb409645.aspx&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;A class=techtag href="http://technorati.com/tag/C#" rel=tag&gt;C#&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Coach" rel=tag&gt;Coach&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Formation" rel=tag&gt;Formation&lt;/A&gt; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2546887" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>Gadget Academy : lancez-vous !</title><link>http://blogs.msdn.com/laurelle/archive/2007/04/11/gadget-academy-lancez-vous.aspx</link><pubDate>Wed, 11 Apr 2007 11:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2083497</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/2083497.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=2083497</wfw:commentRss><description>&lt;P&gt;Si comme moi, vous êtes un fan de Gadget, que vous aimez les tutoriaux pour vous lancer, alors, la &lt;A class="" href="http://www.microsoft.com/france/msdn/windowsvista/gadgets/default.mspx" mce_href="http://www.microsoft.com/france/msdn/windowsvista/gadgets/default.mspx"&gt;Gadget Academy&lt;/A&gt; est faite pour vous !&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://www.microsoft.com/france/msdn/windowsvista/gadgets/default.mspx" mce_href="http://www.microsoft.com/france/msdn/windowsvista/gadgets/default.mspx"&gt;&lt;IMG style="WIDTH: 750px; HEIGHT: 200px" height=200 src="http://www.microsoft.com/france/msdn/windowsvista/images/gadgets/academy.JPG" width=750 mce_src="http://www.microsoft.com/france/msdn/windowsvista/images/gadgets/academy.JPG"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://benjamingauthey.com/ct.ashx?id=588e191b-2d91-4c5e-84c3-2a82ed395a83&amp;amp;url=http%3a%2f%2fblogs.developpeur.org%2fmalabar"&gt;Lucas&lt;/A&gt; nous en dit un peu plus au travers de&amp;nbsp;cette vidéo (Merci &lt;A class="" href="http://www.benjamingauthey.com/" mce_href="http://www.benjamingauthey.com"&gt;Benjamin&lt;/A&gt; pour la vidéo) :&lt;/P&gt;
&lt;P align=center&gt;&lt;EMBED pluginspage=http://macromedia.com/go/getflashplayer src=http://images.soapbox.msn.com/flash/soapbox1_1.swf width=412 height=362 type=application/x-shockwave-flash quality="high" wmode="transparent" flashvars="c=v&amp;amp;v=93bc1cae-3857-40b6-bc0b-9c83ad99b091"&gt;&lt;/EMBED&gt;&lt;BR&gt;&lt;/P&gt;&lt;A class=techtag href="http://technorati.com/tag/gadget" rel=tag&gt;gadget&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/vista" rel=tag&gt;vista&lt;/A&gt; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2083497" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Web+2.0/default.aspx">Web 2.0</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Etudiants/default.aspx">Etudiants</category></item><item><title>Le blog des TechDays est ouvert !</title><link>http://blogs.msdn.com/laurelle/archive/2006/12/21/le-blog-des-techdays-est-ouvert.aspx</link><pubDate>Thu, 21 Dec 2006 16:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1340192</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/1340192.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=1340192</wfw:commentRss><description>&lt;P&gt;Pour être au courant des dernières infos sur les TechDays, visitez le &lt;A class="" title="Le blog des TechDays" href="http://blogs.technet.com/mstechdays/" mce_href="http://blogs.technet.com/mstechdays/"&gt;blog TechDays&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Pour mémoire, les &lt;B&gt;Microsoft TechDays&lt;/B&gt; auront lieu &lt;STRONG&gt;du lundi 5 au mercredi 7 février&lt;/STRONG&gt; au Palais des Congrès de &lt;STRONG&gt;Paris&lt;/STRONG&gt;. Vous aurez l'occasion, lors de la première édition de cet événement exceptionnel, de faire le point sur &lt;B&gt;tous les produits, technologies et solutions Microsoft.&lt;/B&gt;&lt;BR&gt;Ce sont plus de 220 sessions, des labs, des workshop (ce sont des ateliers qui permettent de manipuler les produits assistés par un animateur et des personnes pour aider en cas de question, bref, une formation :-))&lt;/P&gt;
&lt;P&gt;Inscrivez-vous vite sur &lt;A href="http://www.microsoft.com/france/mstechdays/" mce_href="http://www.microsoft.com/france/mstechdays/"&gt;&lt;FONT color=#0000cc&gt;http://www.microsoft.com/france/mstechdays/&lt;/FONT&gt;&lt;/A&gt; &lt;/P&gt;&lt;BR&gt;&lt;A class=techtag href="http://technorati.com/tag/techdays2007" rel=tag&gt;techdays2007&lt;/A&gt; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1340192" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Web+2.0/default.aspx">Web 2.0</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Vista/default.aspx">Vista</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Architecte/default.aspx">Architecte</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/TechDays/default.aspx">TechDays</category></item><item><title>Microsoft TechDays : c'est parti - 5, 6 et 7 février - 220 sessions pour les développeurs et les IT Pro !</title><link>http://blogs.msdn.com/laurelle/archive/2006/12/05/microsoft-techdays-c-est-parti-5-6-et-7-f-vrier-220-sessions-pour-les-d-veloppeurs-et-les-it-pro.aspx</link><pubDate>Tue, 05 Dec 2006 23:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1212442</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/1212442.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=1212442</wfw:commentRss><description>&lt;P&gt;&lt;IMG title="Microsoft TechDays" style="WIDTH: 1000px; HEIGHT: 93px" height=93 alt="Microsoft TechDays" src="http://www.microsoft.com/france/mstechdays/images/bandeau.jpg" width=1000 mce_src="http://www.microsoft.com/france/mstechdays/images/bandeau.jpg"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Les &lt;B&gt;Microsoft TechDays&lt;/B&gt; auront lieu &lt;STRONG&gt;du lundi 5 au mercredi 7 février&lt;/STRONG&gt; au Palais des Congrès de &lt;STRONG&gt;Paris&lt;/STRONG&gt;. Vous aurez l'occasion, lors de la première édition de cet événement exceptionnel, de faire le point sur &lt;B&gt;tous les produits, technologies et solutions Microsoft.&lt;/B&gt;&lt;BR&gt;Nous vous proposons d'assister &lt;B&gt;gratuitement&lt;/B&gt; à :&lt;/P&gt;
&lt;UL id=liste_encadre&gt;
&lt;LI&gt;Plus de 200 sessions 
&lt;LI&gt;Des rencontres avec des partenaires experts sur un véritable village de plus de 50 exposants 
&lt;LI&gt;Des rencontres avec des communautés spécialisées 
&lt;LI&gt;Des ateliers techniques 
&lt;LI&gt;Des hands on lab... &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Pour ceux qui connaissaient les DevDays, cette nouvelle conférence remplace les DevDays. En mieux ? Clairement, ce sont les DevDays puissance 10 !! Rien que ça :-) &lt;/P&gt;
&lt;P&gt;Inscritpions sur : &lt;A href="http://www.microsoft.com/france/mstechdays/" mce_href="http://www.microsoft.com/france/mstechdays/"&gt;http://www.microsoft.com/france/mstechdays/&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Il y a 15 parcours, 3 focus pour trouver au mieux les sessions adaptée à chacun. Au programme, des sessions sur Visual Basic, l'accès aux données, de l'Architecture, de la sécurité, du management, de l'innovation, des technos du futur, du Web 2.0, bref de tout !&lt;/P&gt;
&lt;P&gt;Inscrivez-vous sans tarder. En plus c'est gratuit !&lt;/P&gt;&lt;A class=techtag href="http://technorati.com/tag/techdays2007" rel=tag&gt;techdays2007&lt;/A&gt; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1212442" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Web+2.0/default.aspx">Web 2.0</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Infrastructure/default.aspx">Infrastructure</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Vista/default.aspx">Vista</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Architecte/default.aspx">Architecte</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/TechDays/default.aspx">TechDays</category></item><item><title>J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 10)</title><link>http://blogs.msdn.com/laurelle/archive/2006/10/18/j-ai-hack-mon-onduleur-ou-le-reverse-engineering-de-protocoles-de-communication-part-10.aspx</link><pubDate>Wed, 18 Oct 2006 23:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:839994</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/839994.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=839994</wfw:commentRss><description>&lt;P&gt;Me voici déjà au dixième post de ma série. J'ai déjà décrypté &lt;A href="http://blogs.msdn.com/laurelle/archive/2006/08/15/701080.aspx" mce_href="http://blogs.msdn.com/laurelle/archive/2006/08/15/701080.aspx"&gt;le protocole de communication&lt;/A&gt; de mon onduleur. J'ai implémenté toutes les fonctions nécessaires à une &lt;A href="http://blogs.msdn.com/laurelle/archive/2006/08/15/701080.aspx" mce_href="http://blogs.msdn.com/laurelle/archive/2006/08/15/701080.aspx"&gt;gestion de cet onduleur&lt;/A&gt; avec des propriétés qui permettent de lire les données de courant, tension, etc. J'y ai ajouté des &lt;A href="http://blogs.msdn.com/laurelle/archive/2006/09/01/735774.aspx" mce_href="http://blogs.msdn.com/laurelle/archive/2006/09/01/735774.aspx"&gt;événements&lt;/A&gt; qui se déclenchent en cas de panne électrique, de batterie faible, etc. Me voilà donc avec une classe complète prête à être utiliser. &lt;/P&gt;
&lt;P&gt;Comme mon code est destiné à fonctionner notamment sur un serveur, il est obligatoire que ma classe soit gérée dans une application de type service Windows. Un service fonctionne quoi qu'il arrive, quelque soit l'utilisateur connecté ou non. Il lui est possible d'interagir avec le bureau Windows dans certains cas quand un utilisateur est connecté. &lt;/P&gt;
&lt;P&gt;Un service fonctionne sous un compte utilisateur. Cela lui donne donc les droits liés à cet utilisateur. Il existe un utilisateur un peu particulier qui est le compte System. En général, souvent pour se simplifier la vie, la plupart des services fonctionnent avec ce compte. &lt;/P&gt;
&lt;P&gt;Côté démarrage, il est possible d'opter pour 3 solutions&amp;nbsp;: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Arrêté (bon, ça ne sert pas à grand-chose sauf quand le service est piloté par une autre application, ce qui peut être parfois le cas). &lt;/LI&gt;
&lt;LI&gt;Manuel&amp;nbsp;: le service ne démarre que si l'utilisateur le souhaite ou si un service nécessitant ce service démarre (cas d'une dépendance) &lt;/LI&gt;
&lt;LI&gt;Automatique&amp;nbsp;: le service se lance automatiquement avec Windows &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Voilà pour les généralités. Maintenant, écrire un service en .NET nécessite d'écrire le service en tant que tel mais aussi une classe spécifique qui va permettre d'installer le service. J'y reviendrais plus loin. Comme je l'ai indiqué dans &lt;A href="http://blogs.msdn.com/laurelle/archive/2006/08/06/690277.aspx" mce_href="http://blogs.msdn.com/laurelle/archive/2006/08/06/690277.aspx"&gt;mon premier post&lt;/A&gt;, j'ai décidé d'utiliser les &lt;A href="http://www.microsoft.com/france/msdn/vstudio/express/default.mspx" mce_href="http://www.microsoft.com/france/msdn/vstudio/express/default.mspx"&gt;versions Express de Visual Studio&lt;/A&gt;, gratuite pour tout le monde, pour faire mon développement et notamment VB Express. Les versions Express permettent de faire du développement .NET et sont déjà très complètes. Elles ont des limitations notamment dans les templates qui permettent de faciliter le développement. Les autres limitations sont liées au débugage. Dans le cas de mon service, écrire un service en VB Express m'a demandé beaucoup de temps. Certainement la partie la plus longue. Le débugage m'a été impossible. J'ai fait le test a posteriori avec &lt;A href="http://www.microsoft.com/france/msdn/vstudio/gamme.mspx" mce_href="http://www.microsoft.com/france/msdn/vstudio/gamme.mspx"&gt;une version Visual Studio Pro&lt;/A&gt; et si je l'avais développer avec cette version, cela m'aurais fait gagner beaucoup de temps. &lt;/P&gt;
&lt;P&gt;Je vais quand même expliquer comment créer un service avec les versions Express. &lt;/P&gt;
&lt;P&gt;Il faut, comme je l'ai indiqué, créer une classe d'installation du service. Cette classe doit s'appeler ProjectInstaller et doit hériter de System.Configuration.Install.Installer &lt;/P&gt;
&lt;P&gt;Voici le code nécessaire à l'installation d'un service&amp;nbsp;: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;RunInstaller(&lt;SPAN style="COLOR: blue"&gt;True&lt;/SPAN&gt;)&amp;gt; &lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; ProjectInstaller &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Inherits&lt;/SPAN&gt; System.Configuration.Install.Installer&lt;/SPAN&gt; &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt;() &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;MyBase&lt;/SPAN&gt;.New() &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;myServiceProcessInstaller &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; System.ServiceProcess.ServiceProcessInstaller &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;ServiceOnduleurInstaller &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; System.ServiceProcess.ServiceInstaller &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;myServiceProcessInstaller = &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; System.ServiceProcess.ServiceProcessInstaller &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;ServiceOnduleurInstaller = &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; System.ServiceProcess.ServiceInstaller &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;'ServiceProcessInstaller &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;myServiceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;myServiceProcessInstaller.Password = &lt;SPAN style="COLOR: blue"&gt;Nothing &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;myServiceProcessInstaller.Username = &lt;SPAN style="COLOR: blue"&gt;Nothing &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;'ServiceOnduleurInstaller &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;ServiceOnduleurInstaller.DisplayName = &lt;SPAN style="COLOR: maroon"&gt;"Service Onduleur" &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;ServiceOnduleurInstaller.ServiceName = &lt;SPAN style="COLOR: maroon"&gt;"Service Onduleur" &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;ServiceOnduleurInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;'ProjectInstaller &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;Installers.AddRange(&lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; System.Configuration.Install.Installer() { myServiceProcessInstaller, ServiceOnduleurInstaller}) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Comme expliqué dans les généralités des services, il est nécessaire de déterminer sous quel compte et quel va être le type de démarrage du service. C'est là aussi que le nom du service est écrit en dur. C'est le nom qui apparaît dans la console d'administration des services. &lt;/P&gt;
&lt;P&gt;Pour revenir sur le cas du compte System, ce compte est comme toutes les autres, il possède un login et un mot de passe. Cependant, dans le cas de l'initialisation du compte pour une utilisation avec le compte System, il faut spécifier ServiceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem et ne pas oublier les deux lignes ServiceProcessInstaller.Password = Nothing et ServiceProcessInstaller.Username = Nothing. Si une de ces variables est modifiée, il y a des chances que le lancement du service ne fonctionne pas car les informations de compte stockées pourraient être étonnées. &lt;/P&gt;
&lt;P&gt;Une fois la classe ProjectInstaller d'écrite, il reste le service en tant que tel à écrire. Voici une classe de base qui associée à la classe précédente fonctionne. &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; ServiceOnduleur &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Inherits&lt;/SPAN&gt; System.ServiceProcess.ServiceBase &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt;() &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;MyBase&lt;/SPAN&gt;.New() &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.ServiceName = &lt;SPAN style="COLOR: maroon"&gt;"Service Onduleur" &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;' C'est par ici que le service sera initialisé &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;lt;MTAThread()&amp;gt; &lt;SPAN style="COLOR: blue"&gt;Shared&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; Main() &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Dim&lt;/SPAN&gt; ServicesToRun() &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; System.ServiceProcess.ServiceBase &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;' Démarrage du service dans le process &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;ServicesToRun = &lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; System.ServiceProcess.ServiceBase() {&lt;SPAN style="COLOR: blue"&gt;New&lt;/SPAN&gt; ServiceOnduleur} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;System.ServiceProcess.ServiceBase.Run(ServicesToRun) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Protected&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Overrides&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; OnStart(&lt;SPAN style="COLOR: blue"&gt;ByVal&lt;/SPAN&gt; args() &lt;SPAN style="COLOR: blue"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;' Initialisation du service pour le démarrage &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;Protected&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Overrides&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub&lt;/SPAN&gt; OnStop() &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;' Code qui arrête le service &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Sub &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;End&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;Class&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;La classe service doit être publique et héritée de la classe System.ServiceProcess.ServiceBase. Elle doit avoir un point d'entrée (ici Shared Main) qui initialise le service. L'initialisation se fait en créant une nouvelle classe ServiceBase et en le démarrant. Il est possible de démarrer plusieurs services dans le même process. Pour cela, il suffit de faire comme suit&amp;nbsp;: &lt;/P&gt;
&lt;P&gt;ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService} &lt;/P&gt;
&lt;P&gt;Le minimum pour une classe de type service est d'implémenter une méthode OnStart et une autre OnStop. Comme leurs noms l'indiquent, dans le OnStart, il faut initialiser le service pour qu'il démarre et dans le OnStop ce qu'il faut pour qu'il s'arrête. &lt;/P&gt;
&lt;P&gt;Avec cette classe service, la gestion de l'onduleur, l'envoie d'email, j'ai maintenant tout ce qu'il faut pour écrire un service complet qui me permette de gérer mes onduleurs. Stay tune, il y aura peut-être une suite&amp;nbsp;:-) &lt;/P&gt;&lt;A class=techtag href="http://technorati.com/tag/VB" rel=tag&gt;VB&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Visual%20Basic" rel=tag&gt;Visual Basic&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Visual%20Studio" rel=tag&gt;Visual Studio&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Express" rel=tag&gt;Express&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/VS" rel=tag&gt;VS&lt;/A&gt; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=839994" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 9)</title><link>http://blogs.msdn.com/laurelle/archive/2006/09/14/753746.aspx</link><pubDate>Thu, 14 Sep 2006 12:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:753746</guid><dc:creator>laurelle</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/753746.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=753746</wfw:commentRss><description>&lt;p&gt;Comme indiqué dans mon &lt;a href="http://blogs.msdn.com/laurelle/archive/2006/09/01/735774.aspx"&gt;précédent post&lt;/a&gt;, je vais expliquer le fonctionnement d'un timer. Très utilise lorsqu'on souhaite faire une action spécifique à intervalle régulier. Je vais également en profiter pour montrer comment créer une propriété en lecture et écriture. En plus, je vais expliquer comment lever des exceptions dans son propre code. 
&lt;/p&gt;&lt;p&gt;Une bonne partie de tout cela se trouve condensé dans la fonction d'ouverture de l'onduleur. Voici donc le code avec les déclarations de variables et constantes nécessaires à la compréhension.
&lt;/p&gt;&lt;p&gt;    
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Const&lt;/span&gt; ERREUR_IDENTITE = &lt;span style="color:maroon"&gt;"Impossible d'obtenir l'identité de l'onduleur"
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Const&lt;/span&gt; ERREUR_ALIM_BATTERIE = &lt;span style="color:maroon"&gt;"Impossible d'obtenir les informations de batterie"
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Const&lt;/span&gt; ERREUR_ALIM_SECTEUR = &lt;span style="color:maroon"&gt;"Impossible d'obtenir les informations de secteur"
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt; Const&lt;/span&gt; PERIOD_APPEL = 3000 &lt;span style="color:green"&gt;'2 secondes = 2000 milisecondes
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Private&lt;/span&gt; myPeriodeAppel &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;Integer&lt;/span&gt; = PERIOD_APPEL
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Private&lt;/span&gt; myPort &lt;span style="color:blue"&gt;As&lt;/span&gt; SerialPort
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Private&lt;/span&gt; myPortSerie &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;String&lt;/span&gt; = &lt;span style="color:maroon"&gt;""&lt;/span&gt;
			&lt;span style="color:green"&gt;'stocke le nom du port
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Private&lt;/span&gt; myTimer &lt;span style="color:blue"&gt;As&lt;/span&gt; Timer
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Function&lt;/span&gt; Ouvrir(&lt;span style="color:blue"&gt;ByVal&lt;/span&gt; StrPort &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;String&lt;/span&gt;) &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;Boolean
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Try
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'ouvre le port série avec le bonnes infos
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myPortSerie = StrPort
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myPort = &lt;span style="color:blue"&gt;New&lt;/span&gt; SerialPort(StrPort, 2400, Ports.Parity.None, 8, Ports.StopBits.One)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'le caractère de fin de ligne est chr(13), c'est à dire Entrée
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myPort.NewLine = Chr(13)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'délais d'attente de 2 secondes
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myPort.ReadTimeout = 2000
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myPort.Open()
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myPort.DtrEnable = &lt;span style="color:blue"&gt;True
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'vérifie que l'on a bien un onduleur et rempli les bonnes fonctions
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt;
			&lt;span style="color:blue"&gt;Not&lt;/span&gt; (EnvoiCommande(OnduleurCommande.Identite)) &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Throw&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; System.Exception(ERREUR_IDENTITE)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt;
			&lt;span style="color:blue"&gt;Not&lt;/span&gt; (EnvoiCommande(OnduleurCommande.Batterie)) &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Throw&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; System.Exception(ERREUR_ALIM_BATTERIE)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt;
			&lt;span style="color:blue"&gt;Not&lt;/span&gt; (EnvoiCommande(OnduleurCommande.Tension)) &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Throw&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; System.Exception(ERREUR_ALIM_SECTEUR)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'toutes les propriétés ont été remplies
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'intialise le timer, récupère les infos toutes les 5 secondes
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myTimer = &lt;span style="color:blue"&gt;New&lt;/span&gt; Timer(&lt;span style="color:blue"&gt;AddressOf&lt;/span&gt; VerifierStatut)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;            myTimer.Change(0, myPeriodeAppel)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt;
			&lt;span style="color:blue"&gt;True
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Catch&lt;/span&gt; ex &lt;span style="color:blue"&gt;As&lt;/span&gt; Exception
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'si ça ne s'ouvre pas, répercute l'exception
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Throw&lt;/span&gt; ex
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt;
			&lt;span style="color:blue"&gt;False
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Try
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Function&lt;/span&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;La fonction Ouvrir prend un paramètre qui doit contenir une chaîne de type COM1, COM2 ou autre permettant d'ouvrir le port série. Le tout se trouve dans un try – catch qui va permet de récupérer les exceptions qui peuvent être levées. En cas de problème, sur le port série, il est important de ne pas laisser planter l'application et de le remonter à l'appelant.
&lt;/p&gt;&lt;p&gt;Sur le même principe, lorsque le port série est ouvert, la fonction EnvoiCommande(OnduleurCommande.Identite) renvoie True si les informations de type modèle, sous modèle, version sont récupérés. Si ce n'est pas le cas, elle renvoie False. Du coup, si un onduleur n'est pas présent, les informations ne seront pas récupérées et False sera renvoyé. Dans ce cas, nous sommes devant un problème et on lève une exception. Cela se fait simplement à l'aide le la ligne Throw New System.Exception("ce que l'on veut envoyer"). Simple et efficace.
&lt;/p&gt;&lt;p&gt;Quand au timer, simple également. Il suffit de déclarer une variable de type Timer, ici myTimer. Ensuite, il faut créer une fonction de callback (rappel). Elle permettra au lors du déclanchement du timer de venir se brancher et d'exécuter le code de la fonction. La fonction de call back s'appelle VerifierStatut. Sa définiton est ci-dessous. L'initialisation se fait donc en indiquant myTimer = New Timer(AdressOf VerifierStatut). AdressOf renvoie un pointeur de la fonction de callback. Il ne reste plus qu'à initialiser le timer : myTimer.Change(0, myPeriodeAppel). 0 indique qu'il doit se déclencher maintenant. Le myPeriodeAppel indique l'intervalle en milli secondes d'appel de la fonction de callback.
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Private&lt;/span&gt;
			&lt;span style="color:blue"&gt;Sub&lt;/span&gt; VerifierStatut(&lt;span style="color:blue"&gt;ByVal&lt;/span&gt; stateInfo &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;Object&lt;/span&gt;)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:green"&gt;'pas de vérification particulière. En cas de problème, les exceptions sont trappées dans la fonction EnvoiCommande
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;        EnvoiCommande(OnduleurCommande.Tension)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Sub
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Dans mon cas, par défaut, lors de l'ouverture de l'onduleur, l'appel se fait toutes les 3000 milli secondes soit toutes les 3 secondes. J'ai implémenté en plus dans ma gestion d'onduleur une propriété qui permet de modifier cette valeur. Je ne sais pas encore par avance tous les combiens de temps, il est nécessaire de l'appeler. Donc, je me garde la possibilité de modifier cette valeur. Cependant, pour des questions de performances, je ne souhaite pas que l'appel soit fait à moins d'une seconde. J'exprime donc ma propriété en secondes et choisi des byte. 
&lt;/p&gt;&lt;p&gt;L'implémentation de la propriété donne cela :
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Property&lt;/span&gt; PeriodeAppel() &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;Byte
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Get
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt; (myPeriodeAppel / 1000)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Get
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;Set&lt;/span&gt;(&lt;span style="color:blue"&gt;ByVal&lt;/span&gt; value &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;Byte&lt;/span&gt;)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt; value &amp;gt; 0 &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;                myPeriodeAppel = value * 1000
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;                myTimer.Change(0, myPeriodeAppel)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Set
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Property
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;La lecture (Get) est simple, je renvoie la période d'appel divisée par 1000 car en interne ma variable est en milli secondes. 
&lt;/p&gt;&lt;p&gt;Pour l'écriture (Set), je vérifie que la valeur est bien supérieur à 0 (donc au moins égale à 1). Je la multiplie par 1000, et je change la période d'appel de mon timer. 
&lt;/p&gt;&lt;p&gt;Avec VB.NET, il est donc très facile de lever des exceptions, facile également d'implémenter et gérer un timer, de mettre en place des propriétés, en lecture et en écriture. Avec un comportement particulier qui modifie l'application dans la partie lecture ou écriture.
&lt;/p&gt;&lt;p&gt;Le prochain post sera certainement consacré à la mise en place d'un service Windows. Seule chose qu'il me reste à faire par rapport à mon &lt;a href="http://blogs.msdn.com/laurelle/archive/2006/08/06/690277.aspx"&gt;ambition d'origine&lt;/a&gt; ! So stay tune…&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=753746" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>Comment installer Visual Studio Express sur Vista RC1</title><link>http://blogs.msdn.com/laurelle/archive/2006/09/07/Comment-installer-Visual-Studio-Express-sur-Vista-RC1.aspx</link><pubDate>Thu, 07 Sep 2006 23:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:744946</guid><dc:creator>laurelle</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/744946.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=744946</wfw:commentRss><description>&lt;P&gt;Hier, j'ai fait le grand saut sur la toute dernière build 552 (la RC1 officielle de Vista). Il m'a fallu 2h30 pour sauvegarder les données et seulement une trentaine de minutes pour installer Vista… J'y ai ajouté Office 12 Beta technical refresh en français. Viens maintenant l'installation de &lt;A href="http://www.microsoft.com/france/msdn/vstudio/express/vbasicexpress.mspx" mce_href="http://www.microsoft.com/france/msdn/vstudio/express/vbasicexpress.mspx"&gt;Visual Basic Express&lt;/A&gt; (version gratuite, comme les autres de la gamme &lt;A href="http://www.microsoft.com/france/msdn/vstudio/express/default.mspx" mce_href="http://www.microsoft.com/france/msdn/vstudio/express/default.mspx"&gt;Visual Studio Express&lt;/A&gt;). &lt;/P&gt;
&lt;P&gt;J'ai suivi les recommandations d'être un simple utilisateur sur ma machine (seulement membre du groupe user). Ca a parfaitement été pour installer Office 12 (moyennant élévation de privilège sur demande automatique de Vista). Ca a également été pour quelques autres applications. &lt;/P&gt;
&lt;P&gt;Par contre, avec Visual Studio Express, ça ne fonctionne pas. Ca a l'air dû à un problème avec le BITS (le background internet transfer service) qui gère les téléchargements en tâche de fond. Du coup, aucun produit de la gamme Express ne s'installe. Une erreur au chargement des produits on line est renvoyée. &lt;/P&gt;
&lt;P&gt;Le contournement consiste donc à s'ajouter au groupe des administrateurs locaux (administrators en anglais ou administreurs en français), de se déloguer et de se reloguer (attention, pour que l'ajout au groupe prenne pleinement effet, il faut se déloguer et se reloguer). &lt;/P&gt;
&lt;P&gt;Ensuite, l'installation se passe sans histoire. Le produit fonctionne parfaitement bien. Il est ensuite possible de se retirer du groupe des administrateurs et le produit continue de parfaitement fonctionner. Attention, suivant le code que vous écrivez, les demandes d'élévation de privilèges vont être nombreuses. En même temps, c'est très bien pour apprendre à écrire du code qui nécessite un minimum de permission.&lt;/P&gt;&lt;A class=techtag href="http://technorati.com/tag/Visual" rel=tag&gt;Visual&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Studio" rel=tag&gt;Studio&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Express" rel=tag&gt;Express&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/Vista" rel=tag&gt;Vista&lt;/A&gt; &lt;A class=techtag href="http://technorati.com/tag/RC1" rel=tag&gt;RC1&lt;/A&gt; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=744946" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/Vista/default.aspx">Vista</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 8)</title><link>http://blogs.msdn.com/laurelle/archive/2006/09/01/735774.aspx</link><pubDate>Fri, 01 Sep 2006 22:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:735774</guid><dc:creator>laurelle</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/735774.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=735774</wfw:commentRss><description>&lt;p&gt;J’ai donc continuer de développer ma solution de &lt;a href="http://blogs.msdn.com/laurelle/archive/2006/08/06/690277.aspx"&gt;gestion d’onduleur&lt;/a&gt;. J’ai profité de mon retour à la maison pour continuer les tests physiques sur mes onduleurs. Oui, j’ai bien dit mes onduleurs. En fait, j’en possède 3 du même modèle. Ce qui a aussi motivé l’écriture de ce service de gestion…  
&lt;/p&gt;&lt;p&gt;La suite des tests m’a permis de compléter &lt;a href="http://blogs.msdn.com/laurelle/archive/2006/08/15/701080.aspx"&gt;le protocole de communication&lt;/a&gt; et de déterminer à quoi  servent la plupart des bits :
&lt;/p&gt;&lt;p&gt;00001000 = statut. 1 bit par info. 
&lt;/p&gt;&lt;p&gt;b0b1b2b3b4b5b6b7
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;b0 = passe à 1 lorsqu’une panne de courant arrive, lorsque l’alimentation est coupée
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;b1 = passe à 1 lorsque la batterie est faible
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;b2 = ??? pas encore déterminé. Impossible en utilisation normale de le faire passer à 1. Il reste à 0.
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;b3 = ??? Idem
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;b4 = est à 1 en fonctionnement normal. Il indique que les sorties sont alimentées
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;b5= passe à 1 quand on est en mode test. Le mode test est déclenché par l’envoie de la commande T
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;b6 = ??? pas non plus réussit à déterminer à quoi ce bit sert
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;b7 = passe à 1 quand l’alimentation est sur batterie
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Cela m’a également permis d’étalonner les niveau de la batterie. Le niveau haut varie de 14 à 10,7. L’échelle de consommation est quasi linéaire.
&lt;/p&gt;&lt;p&gt;Côté code, j’ai décidé d’implémenter des événements. Ainsi, lorsqu’un de ces bits change, j’envoie l’événement correspondant. Cela permet de gérer avec de la souplesse ce qui peut arriver. Il faut d’abord dans le code déclarer les événements :
&lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;&lt;span style="color:green"&gt;'se déclenche lorsque le secteur est coupé, en général va avec l'événement FonctionnementBatterie
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Event&lt;/span&gt; ArretAlimSecteur()
&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;'se déclenche lorsque le secteur est remis (et qu'il était coupé)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Event&lt;/span&gt; RetourAlimSecteur()
&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;'lorsque l'onduleur fonctionne sur batterie
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Event&lt;/span&gt; FonctionnementBatterie()
&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;'ou lorsqu'il fonctionne de nouveau normalement
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Event&lt;/span&gt; ArretFonctionnementBatterie()
&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;'Lorsque la batterie est faible
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Event&lt;/span&gt; BatterieFaible()
&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;'lorsque l'onduleur est arrêté
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Event&lt;/span&gt; OnduleurArrete()
&lt;/p&gt;&lt;/span&gt;&lt;p&gt;Puis, pour chaque bit, on vérifie si un changement d’état s’est passé. Ca donne cela :
&lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;&lt;span style="color:green"&gt;'position 0 = panne secteur
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Dim&lt;/span&gt; BoolTemp &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;Boolean
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;' récupère la valeur (0 ou 1) du bit 0 de la chaîne de 8 bits
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;BoolTemp = Val(mc.Item(7).Value.Substring(0, 1))
&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;If&lt;/span&gt; BoolTemp &amp;lt;&amp;gt; myOnduleurPanneSecteur &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt; BoolTemp &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;RaiseEvent&lt;/span&gt; ArretAlimSecteur()
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Else
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;RaiseEvent&lt;/span&gt; RetourAlimSecteur()
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;    myOnduleurPanneSecteur = BoolTemp
&lt;/p&gt;&lt;p&gt;&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;Le principe est simple, il faut récupérer la valeur dans une variable temporaire. Puis on compare à la valeur actuelle. Si la valeur est la même, alors pas de changement d’état et on ne fait rien. Si les valeurs sont différentes, alors on regarde la valeur de la variable.
&lt;/p&gt;&lt;p&gt;Dans le cas où le bit est à 1, alors cela signifie que le courant a été coupé. On envoie donc l’événement ArretAlimSecteur. Dans le cas où il passe à 0, on peut signifier que le courant est revenu en envoyant l’événement RetourAlimSecteur. Le mot magic RaiseEvent permet d’envoyer l’événement.
&lt;/p&gt;&lt;p&gt;Ne pas oublier à la fin d’attribuer la nouvelle valeur à la variable privée stockant cette information.
&lt;/p&gt;&lt;p&gt;Côté du code qui intercepte les événements, ce n’est pas plus compliqué. Il faut déclarer une variable avec le mot clé WithEvents. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;
			&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;WithEvents&lt;/span&gt; myOnduleur &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; Onduleur
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;On se retrouve ensuite avec une fonction de ce type qui permet d’intercepter l’événement et de le traiter :
&lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;&lt;span style="color:blue"&gt;Private&lt;/span&gt;
			&lt;span style="color:blue"&gt;Sub&lt;/span&gt; myOnduleur_ArretAlimSecteur() &lt;span style="color:blue"&gt;Handles&lt;/span&gt; myOnduleur.ArretAlimSecteur
&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;'Faire quelque chose ici :-)
&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Sub
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;S’il y a des paramètres à passer, cela se passe de la même façon. Il suffit de les décrire dans la définition puis de les envoyer ans le RaiseEvent et de les récupérer comme avec n’importe quel événement dans la fonction Handles. 
&lt;/p&gt;&lt;p&gt;L’utilisation des événements est donc très simple. Un vrai bonheur.
&lt;/p&gt;&lt;p&gt;Avec cela, j’ai fini d’écrire ma classe de gestion de l’onduleur. Elle permet de se connecter à l’onduleur, de récupérer les informations, en cas de panne de courant ou autre, d’envoyer l’événement correspondant. 
&lt;/p&gt;&lt;p&gt;Je récupère les données de façon régulière à l’aide d’un timer. Le fonctionnement d’un timer au prochain post…
&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=735774" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 7)</title><link>http://blogs.msdn.com/laurelle/archive/2006/08/17/704330.aspx</link><pubDate>Thu, 17 Aug 2006 17:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:704330</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/704330.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=704330</wfw:commentRss><description>&lt;p&gt;Me voici donc maintenant avec 3 chaînes de texte à analyser et dont il faut que je ressorte plusieurs informations. Les chaînes sont bien délimitées. Le protocole complet est expliqué dans le &lt;a href="http://blogs.msdn.com/laurelle/archive/2006/08/15/701080.aspx"&gt;sixième post&lt;/a&gt;. 
&lt;/p&gt;&lt;p&gt;Voici les 3 principales chaînes :
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;#BELKIN          Master     1.00      
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;(238.0 237.0 236.0 024 50.0 13.9 32.0 00001000
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;#230.0 2.2 12.00 50.0
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;En temps normal, je rechercherais les espaces, j’extrairai les valeurs entre les espaces et les convertirais. Vu que les chaînes semblent avoir tout le temps la même taille, même pas la peine de regarder les espaces, un extrait de type mid( "#230.0 2.2 12.00 50.0",1,5)  pour le 230.0 suffirait amplement. Chaque partie peut être extraite ainsi. Une simple vérification de longueur de chaîne suffira. Histoire de compliquer un peu la chose et surtout dans la philosophie de me remettre au code et d’apprendre de nouvelles choses, je me suis dit que je regarderais bien les expressions régulières. Et là, le bonheur. Je connaissais un peu la théorie mais pas du tout la pratique. Et je me suis bien amusé :-). 
&lt;/p&gt;&lt;p&gt;Comme toujours, j’ai commencé par rechercher de l’info sur le sujet. D’abord la doc officielle sur le sujet (bof), puis des exemples sur MSDN (mieux) et dans les communautés (mieux). Je suis tombé sur pas mal d’applications qui permettaient de valider et tester ces expressions régulières et même de générer le code associé. Bien pratique pour se mettre en jambe. 
&lt;/p&gt;&lt;p&gt;J’ai donc suivi quelques tutoriaux, fait quelques exemples et je me suis lancé pour mes propres chaînes. Je suis parti du principe, pour toutes les chaînes, que la taille des chaînes ne varierai pas et qu’elles étaient toujours formées de la même façon. Que si cela n’était pas respecté, il y avait erreur. Que pour la chaîne contenant du texte, il n’y avait que 2 mots renvoyés.  Voici donc un peu de code (toujours pour faire plaisir à &lt;a href="http://www.benjamingauthey.com"&gt;Benjamin&lt;/a&gt;) pour illustrer cela :
&lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Public&lt;/span&gt;
			&lt;span style="color:blue"&gt;Function&lt;/span&gt; DecryptTest(&lt;span style="color:blue"&gt;ByVal&lt;/span&gt; StrCrypter &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;String&lt;/span&gt;, &lt;span style="color:blue"&gt;ByVal&lt;/span&gt; IntTypeCrypter &lt;span style="color:blue"&gt;As&lt;/span&gt; OnduleurCommande) &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;Boolean
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Select&lt;/span&gt;
			&lt;span style="color:blue"&gt;Case&lt;/span&gt; IntTypeCrypter
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Case&lt;/span&gt; OnduleurCommande.Identite
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;' on décrypte le I : #BELKIN          Master     1.00      
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; re &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; Regex(&lt;span style="color:maroon"&gt;"\b[A-Za-z].*?\b|\b\d\.\d\d\b"&lt;/span&gt;)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; mc &lt;span style="color:blue"&gt;As&lt;/span&gt; MatchCollection
&lt;/p&gt;&lt;p&gt;                mc = re.Matches(StrCrypter)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt; mc.Count = 3 &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;                    myModele = mc.Item(0).Value
&lt;/p&gt;&lt;p&gt;                    mySousModele = mc.Item(1).Value
&lt;/p&gt;&lt;p&gt;                    myModeleVersion = mc.Item(2).Value
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Else
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt;
			&lt;span style="color:blue"&gt;False
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;
 &lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Case&lt;/span&gt; OnduleurCommande.AlimentationBatterie
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;' on décrypte le F : #230.0 2.2 12.00 50.0
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; re &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; Regex(&lt;span style="color:maroon"&gt;"\b\d\d\d\.\d\b|\b\d\.\d\b|\b\d\d\.\d\d\b|\b\d\d\.\d"&lt;/span&gt;)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; mc &lt;span style="color:blue"&gt;As&lt;/span&gt; MatchCollection
&lt;/p&gt;&lt;p&gt;                mc = re.Matches(StrCrypter)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt; mc.Count = 4 &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;                    myTensionSortieBatterie = Val(mc.Item(0).Value)
&lt;/p&gt;&lt;p&gt;                    myAmperageBatterie = Val(mc.Item(1).Value)
&lt;/p&gt;&lt;p&gt;                    myTensionBatterie = Val(mc.Item(2).Value)
&lt;/p&gt;&lt;p&gt;                    myFrequenceSortieBatterie = Val(mc.Item(3).Value)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Else
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt;
			&lt;span style="color:blue"&gt;False
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;
 &lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Case&lt;/span&gt; OnduleurCommande.AlimentationSecteur
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;' on décrypte le Q1 : (238.0 237.0 236.0 024 50.0 13.9 32.0 00001000
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; re &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; Regex(&lt;span style="color:maroon"&gt;"\b\d\d\d\.\d\b|\b\d\d\d\b|\b\d\d\.\d\b|\b\d\d\d\d\d\d\d\d"&lt;/span&gt;)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; mc &lt;span style="color:blue"&gt;As&lt;/span&gt; MatchCollection
&lt;/p&gt;&lt;p&gt;                mc = re.Matches(StrCrypter)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;If&lt;/span&gt; mc.Count = 8 &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;                    myTensionAlim = Val(mc.Item(0).Value)
&lt;/p&gt;&lt;p&gt;                    myTensionSortiePrimaire = Val(mc.Item(1).Value)
&lt;/p&gt;&lt;p&gt;                    myTensionSortieSecondaire = Val(mc.Item(2).Value)
&lt;/p&gt;&lt;p&gt;                    myPourcentageChargeOnduleur = Val(mc.Item(3).Value)
&lt;/p&gt;&lt;p&gt;                    myFrequence = Val(mc.Item(4).Value)
&lt;/p&gt;&lt;p&gt;                    myPourcentageChargeBatterie = (Val(mc.Item(5).Value) / 14.0 * 100.0)
&lt;/p&gt;&lt;p&gt;                    myTemperature = Val(mc.Item(6).Value)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;' on s’occupera plus tard de la chaîne de 8 caractères
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Else
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt;
			&lt;span style="color:blue"&gt;False
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;If
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Case&lt;/span&gt;
			&lt;span style="color:blue"&gt;Else
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt;
			&lt;span style="color:blue"&gt;False
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Select
&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;
			&lt;span style="color:blue"&gt;Return&lt;/span&gt;
			&lt;span style="color:blue"&gt;True
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Function&lt;/span&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Pour lire le code, tous les myQuelqueChose sont des variables privées qui contiennent toutes les propriétés de l’onduleur.  Le type dépend de la variable à stocker. La fonction Val a l’avantage d’être surchargée et de renvoyer des types standards.
&lt;/p&gt;&lt;p&gt;Analysons l’extraction des informations de la chaîne Q1. Création d’une expression régulière :
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;span style="color:blue"&gt;Dim&lt;/span&gt; re &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; Regex(&lt;span style="color:maroon"&gt;"\b\d\d\d\.\d\b|\b\d\d\d\b|\b\d\d\.\d\b|\b\d\d\d\d\d\d\d\d"&lt;/span&gt;)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Création d’une collection d’informations (type String) renvoyées par le passage à l’expression régulière :
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;span style="color:blue"&gt;Dim&lt;/span&gt; mc &lt;span style="color:blue"&gt;As&lt;/span&gt; MatchCollection
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Passage de l’expression régulière sur la chaîne de caractère StrCrypter qui contient (238.0 237.0 236.0 024 50.0 13.9 32.0 00001000 :
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;mc = re.Matches(StrCrypter)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;S’il y a eu 8 morceaux trouvés alors c’est OK et on décrypte la chaîne :
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;span style="color:blue"&gt;If&lt;/span&gt; mc.Count = 8 &lt;span style="color:blue"&gt;Then
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Comment fonctionne l’expression régulière ? Avant de répondre, je précise que je ne suis pas devenu un expert en quelques jours donc, il y a peut-être mieux que ce que j’ai fait, plus simple ou plus compliqué. Mais en tout cas, cela fonctionne très bien :
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;\b\d\d\d\.\d\b :
&lt;/div&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;\d signifie valeur numérique, c’est la même chose que lorsqu’on écrit [0-9], je ne me prive donc pas d’utiliser le raccourci :-)
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;\. Désigne le point en tant que tel. Si . est utilisé seul, il désigne n’importe quel caractère.
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;\b indique qu’il faut qu’il y ait un espace ou une ponctuation avant le caractère 
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;Cette expression me permet d’extraire les 3 premières chaînes de type 238.0
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;div&gt;|\b\d\d\d\b :
&lt;/div&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;| signifie ou logique. Ce qui suit sera donc extrait en plus de ce qui précède
&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;3 \d indique 3 chiffres associé au \b du début, il permet d’extraire le 024
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;div&gt;|\b\d\d\.\d\b :
&lt;/div&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Rien de nouveau dans cette expression, même logique que la première. Elle permet d’extraire les 50.0, 13.9 et 32.0
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;div&gt;|\b\d\d\d\d\d\d\d\d :
&lt;/div&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;Tout simple, récupère les 8 derniers chiffres
&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;La collection dans les recherches est toujours remplie dans l’ordre où les éléments ont été trouvés. Il ne me reste donc plus qu’après à remplir mes variables privées avec les informations trouvées, dans l’ordre où elles apparaissent.
&lt;/p&gt;&lt;p&gt;Côté du texte, j’ai un peu rusé et utilisé une combine. L’expression  \b[A-Za-z].*?\b me permet d’extraire une chaîne de texte située entre 2 espaces ou ponctuation quelque soit la longueur de la chaîne.  Tout réside dans le qualificateur paresseux *? qui permet de renvoyer aussi peu de répétition que possible. Associé au \b qui le suit et au . qui le précède, il renvoie donc  ce qui se trouve avant les ponctuations. Et permet de découper les mots. Je sens que je vais le garder dans mes favoris :-)
&lt;/p&gt;&lt;p&gt;J’aurais également pu valider que la chaîne comprenait bien BELKIN, Master et 1.00 en utilisant l’expression régulière BELKIN|Master|1\.00 qui doit me renvoyer 3 chaînes. J’ai préféré l’autre solution car elle me paraissait un peu plus souple. Et surtout parce que j’étais tout fier d’avoir trouvé une expression sympa pour séparer les mots ! Cela rend mon code un  peu plus générique et permettra une utilisation avec un autre type d’onduleur utilisant le même protocole.
&lt;/p&gt;&lt;p&gt;Me voilà donc maintenant bien avancé avec mon protocole presque complet, le code qui permet de le décrypter, mon code d’envoi de mail. Il me reste donc à coder un peu d’intelligence pour permettre la remontée d’alerte, l’utilisation en tant que service Windows (hors de question de devoir être logué pour que ce programme fonctionne) et coder la communication avec l’onduleur. Bref, stay tune, la suite dans les prochains posts.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=704330" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>Développer ses propres jeux pour XBOX 360 : c’est possible !</title><link>http://blogs.msdn.com/laurelle/archive/2006/08/15/701120.aspx</link><pubDate>Tue, 15 Aug 2006 15:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:701120</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/701120.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=701120</wfw:commentRss><description>&lt;p&gt;Et oui, plus besoin d’être une société pignon sur rue dans le développement de jeu pour développer ses propres jeux pour XBOX 360. C’est possible grâce à XNA Game Studio Express. Plus d’infos sur : &lt;a href="http://www.microsoft.com/presspass/press/2006/aug06/08-13XNAGameStudioPR.mspx"&gt;http://www.microsoft.com/presspass/press/2006/aug06/08-13XNAGameStudioPR.mspx&lt;/a&gt;
	&lt;/p&gt;&lt;p&gt;Une news officielle attendue depuis longtemps dans la communauté des développeurs. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=701120" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/XBOX/default.aspx">XBOX</category></item><item><title>J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 6)</title><link>http://blogs.msdn.com/laurelle/archive/2006/08/15/701080.aspx</link><pubDate>Tue, 15 Aug 2006 14:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:701080</guid><dc:creator>laurelle</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/701080.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=701080</wfw:commentRss><description>&lt;P&gt;Voici la suite des aventures de l’analyse du protocole de communication expliqué dans la &lt;A href="http://blogs.msdn.com/laurelle/archive/2006/08/09/693658.aspx"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;U&gt;quatrième partie&lt;/U&gt;&lt;/SPAN&gt;&lt;/A&gt;. J’ai donc essayé à partir des commandes envoyées à l’onduleur de compléter ce que j’ai trouvé en écoutant la conversation entre l’application livrée avec l’onduleur et l’onduleur. J’ai donc utilisé l’application développée précédemment pour envoyer les commandes. Je notais le résultat de chaque commande. Ensuite, j’ai essayé à partir de l’application livrée avec et des informations renvoyées de déchiffrer les résultats. Avoir une application existante aide grandement, cela facilite la comparaison des résultats. Sinon, il faut essayer de deviner par tâtonnement. Moins drôle. Il me reste quelques zones d’incertitude cependant que je vais devoir approfondir. Pour les commandes que je n’avais pas (exemple S), j’ai tout simplement envoyé chaque lettre de l’alphabet et j’ai attendu le retour. La plupart du temps, c’est un écho, assez classique dans les protocoles. Quand rien ne revenait, j’analysais l’onduleur lui-même. Parfois rien ne se passait du tout (exemple envoi de la commande Q). Cela impliquait qu’il pouvait manquer une lettre/chiffre derrière ou que le mode était déjà enclenché (exemple commande C quand on est déjà en courant continue). 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande I &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Renvoie l’identifiant de l’onduleur&amp;nbsp;: #BELKIN Master 1.00 &lt;/P&gt;
&lt;P&gt;1 caractère # qui identifie le début de la chaîne &lt;/P&gt;
&lt;P&gt;16 caractères qui contiennent la marque de l’onduleur, ici BELKIN &lt;/P&gt;
&lt;P&gt;11 caractères qui contiennent le modèle de l’onduleur, ici Master &lt;/P&gt;
&lt;P&gt;11 caractères qui contiennent la version du firmware ici 1.00 &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande S &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Arrête l’onduleur. Attention, si l’onduleur est alimenté en courant il se remet en marche automatiquement. Commande à utiliser donc de préférence lors d’une coupure de courant si besoin. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande T &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Passe l’onduleur en mode batterie test pendant 10s. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande C &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Repasse l’onduleur en mode alimentation par secteur. Utile lorsqu’on force l’onduleur à se mettre en mode batterie avec la commande TL ou T. Pas de différence visible avec la commande CT. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande TL &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Passe l’onduleur en mode batterie. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande CT &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Repasse l’onduleur en mode alimentation par secteur. Voir commande C. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande Q1 &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Renvoie un statut des tensions, fréquences, températures et charges : (238.0 237.0 236.0 024 50.0 13.9 32.0 00001000 &lt;/P&gt;
&lt;P&gt;238.0 = Voltage d’alimentation = 238.0 V &lt;/P&gt;
&lt;P&gt;237.0 = Voltage tension de sortie primaire (&amp;nbsp;?) = 237.0 V &lt;/P&gt;
&lt;P&gt;236.0 =&amp;nbsp;Voltage tension de sortie secondaire (&amp;nbsp;?) = 236.0 V &lt;/P&gt;
&lt;P&gt;024 = charge de l’onduleur en % &lt;/P&gt;
&lt;P&gt;50.0 = fréquence en Hertz &lt;/P&gt;
&lt;P&gt;13.9 =&amp;nbsp;Charge de la batterie&amp;nbsp;(?), reste à déterminer l’échelle, a priori 14. &lt;/P&gt;
&lt;P&gt;32.0 = température en °C &lt;/P&gt;
&lt;P&gt;00001000 = statut. 1 bit par info. Pas encore déterminé l’utilité de tous les bits. Tests à effectuer &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Commande F &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Renvoie un statut de la batterie&amp;nbsp;: #230.0 2.2 12.00 50.0 &lt;/P&gt;
&lt;P&gt;230.0 = Voltage de la sortie batterie &lt;/P&gt;
&lt;P&gt;2.2 = courant en ampère &lt;/P&gt;
&lt;P&gt;12.00 = tension de la batterie &lt;/P&gt;
&lt;P&gt;50.0 = Fréquence de sortie &lt;/P&gt;
&lt;P&gt;Je suis content de ce premier jet de résultat qu’il me reste à approfondir avec quelques tests complémentaires. Cela vade toute façon me permettre d’avancer rapidement dans l’écriture d’une classe de gestion de l’onduleur. A suivre au prochain post&amp;nbsp;!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=701080" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item><item><title>J’ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 5)</title><link>http://blogs.msdn.com/laurelle/archive/2006/08/12/696561.aspx</link><pubDate>Sat, 12 Aug 2006 16:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:696561</guid><dc:creator>laurelle</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/laurelle/comments/696561.aspx</comments><wfw:commentRss>http://blogs.msdn.com/laurelle/commentrss.aspx?PostID=696561</wfw:commentRss><description>&lt;p&gt;Dans mon &lt;a href="http://blogs.msdn.com/laurelle/archive/2006/08/06/690277.aspx"&gt;premier post&lt;/a&gt;, j’indiquais avoir trouvé en quelques minutes comment faire pour envoyer un mail en SMTP. Parce que ce n’est tout de même pas si simple si le serveur SMTP nécessite une authentification et toujours pour faire plaisir à &lt;a href="http://www.benjamingauthey.com"&gt;Benjamin&lt;/a&gt; qui trouve que je n’ai pas écrit assez de code, voici ce qu’il faut écrire :
&lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;'objet mail 
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; email &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; MailMessage(&lt;span style="color:maroon"&gt;"from@mail.fr"&lt;/span&gt;, &lt;span style="color:maroon"&gt;"to@mail.fr"&lt;/span&gt;)
&lt;/p&gt;&lt;p&gt;&lt;span style="color:green"&gt;        'le nom du serveur SMTP ou son adresse IP
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Dim&lt;/span&gt; MonSmtpMail &lt;span style="color:blue"&gt;As&lt;/span&gt;
			&lt;span style="color:blue"&gt;New&lt;/span&gt; SmtpClient(&lt;span style="color:maroon"&gt;"smtp.mail.fr"&lt;/span&gt;) 
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;'sujet du message 
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;        email.Subject = &lt;span style="color:maroon"&gt;"Test message onduleur"
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;'corps du message 
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;        email.Body = &lt;span style="color:maroon"&gt;"Ceci est un message de test pour l'envoie du mail à travers l'onduleur"
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;'indique qu'il ne faut pas utiliser les informations de sécurité de l'utisilateur
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;        MonSmtpMail.UseDefaultCredentials = &lt;span style="color:blue"&gt;False
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;'crée un nouveau credential
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;        MonSmtpMail.Credentials = &lt;span style="color:blue"&gt;New&lt;/span&gt; Net.NetworkCredential(&lt;span style="color:maroon"&gt;"login"&lt;/span&gt;, &lt;span style="color:maroon"&gt;"motdepasse"&lt;/span&gt;)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;'indique qu'il faut envoyer le mail par le réseau
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;        MonSmtpMail.DeliveryMethod = SmtpDeliveryMethod.Network
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:green"&gt;'gestion d'erreur 
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Try
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;            MonSmtpMail.Send(email)
&lt;/p&gt;&lt;/span&gt;&lt;p&gt;
 &lt;/p&gt;&lt;span style="font-family:Courier New; font-size:10"&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;Catch&lt;/span&gt; ex &lt;span style="color:blue"&gt;As&lt;/span&gt; Exception
&lt;/p&gt;&lt;p&gt;            MessageBox.Show(ex.Message)
&lt;/p&gt;&lt;p&gt;
			&lt;span style="color:blue"&gt;End&lt;/span&gt;
			&lt;span style="color:blue"&gt;Try
&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;La vraie ruse se trouve dans l’utilisation du NetWorkCredential qui permet de créer des informations de sécurité avec un login, un mot de passe et un domaine (optionnel).
&lt;/p&gt;&lt;p&gt;S’il n’y a pas besoin d’authentification, ou si l’authentification est intégrée, alors les 3 lignes avant le try ne sont pas nécessaires.
&lt;/p&gt;&lt;p&gt;Alors Benj, t’en penses quoi de ce code ?
&lt;/p&gt;&lt;p&gt;La suite au prochain post…&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=696561" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/laurelle/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/VS/default.aspx">VS</category><category domain="http://blogs.msdn.com/laurelle/archive/tags/Express/default.aspx">Express</category></item></channel></rss>