<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Les articles de c2i.fr</title><link>http://c2idotnet.com:80/articles</link><description>Les articles de c2i.fr</description><item><title>A propos de prévisionnistes...</title><link>http://c2idotnet.com:80/articles/a-propos-de-previsionnistes</link><description>&lt;div style="float: left; padding-right: 10px;"&gt;&lt;img alt="R&amp;eacute;union du conseil d'administration d'IDC" src="http://www.c2i.fr/Media/Default/BlogPost/articles/2013-03/boule-de-cristal.jpg" width="425" height="283" /&gt;&lt;br /&gt;R&amp;eacute;union du conseil d'administration d'IDC&lt;/div&gt;
&lt;p&gt;Ce matin, je tombe sur un article sur &lt;a href="http://www.tablette-tactile.net/etudes/selon-idc-191-millions-de-tablettes-seront-vendues-en-2013-137955/"&gt;Tablette-Tactile.net&lt;/a&gt; reprennant &lt;a href="http://www.idc.com/getdoc.jsp?containerId=prUS24002213#.UVUzNMnLTgP"&gt;le dernier rapport d'IDC&lt;/a&gt;. La principale info, c'est que le nombre de tablette vendue en 2013 devrait &amp;ecirc;tre de 191 millions.&lt;/p&gt;
&lt;p&gt;Bon, OK, mais quelques mois auparavent, ils annon&amp;ccedil;aient 172 millions. Ils se seraient donc tromp&amp;eacute;s de 11%. D'abord, ce n'est pas mince comme erreur mais surtout, c'&amp;eacute;tait il y a seulement 3 mois ! (&lt;a href="http://www.idc.com/getdoc.jsp?containerId=prUS23833612#.UVUyucnLTgM"&gt;communiqu&amp;eacute; de presse du 5 D&amp;eacute;c 2012&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;L&amp;agrave; ou cela devient encore plus dr&amp;ocirc;le, c'est qu'ils font des pr&amp;eacute;dictions &amp;agrave; 2017. Leurs pr&amp;eacute;dictions changent radicalement &amp;agrave; 3 mois alors imaginez &amp;agrave; 5 ans ! Donc qu'annoncent-ils &amp;agrave; 5 ans ?&lt;/p&gt;
&lt;p&gt;1/ Android aura 46% de part de march&amp;eacute;.&lt;/p&gt;
&lt;p&gt;2/ iOS 43.5% (pr&amp;eacute;cis &amp;agrave; la virgule pr&amp;egrave;s).&lt;/p&gt;
&lt;p&gt;3/ Windows 7.4%&lt;/p&gt;
&lt;p&gt;4/ Windows RT 2.7%&lt;/p&gt;
&lt;p&gt;Moi je pr&amp;eacute;dis que :&lt;/p&gt;
&lt;p&gt;1/ Android aura moins de 5% de part de march&amp;eacute; car il aura &amp;eacute;t&amp;eacute; abandonn&amp;eacute; par Google 2 ans auparavent (pas assez rentable, car Google Reader),&lt;/p&gt;
&lt;p&gt;2/ iOS aux alentours de 8.562%,&lt;/p&gt;
&lt;p&gt;3/ Microsoft viendra de lancer Windows 12 mais toujours aucun fabricant n'impl&amp;eacute;mentra l'os dans leur machine,&lt;/p&gt;
&lt;p&gt;4/ Auratura Inc. qui viendra de lancer son nouveau cartable num&amp;eacute;rique restera leader du march&amp;eacute; avec 82.5%,&lt;/p&gt;
&lt;p&gt;5/ Blackberry frisera les 6% de part de march&amp;eacute;.&lt;/p&gt;
&lt;p&gt;OK, ca fait plus de 100% mais de toutes fa&amp;ccedil;ons, personnes ne fait la v&amp;eacute;rification des donn&amp;eacute;es.&lt;/p&gt;
&lt;p&gt;Amusons nous quelques secondes et faisons juste le chemin inverse, soit d&amp;eacute;but 2007 : l'iPhone n'existait pas (9/01/2007), l'iPad encore moins, le march&amp;eacute; des tablettes n"existaient m&amp;ecirc;me pas dans les r&amp;ecirc;ves sous h&amp;eacute;ro&amp;iuml;ne&amp;nbsp;du CEO d'IDC.&lt;br /&gt;Le march&amp;eacute; des tablettes commence &amp;agrave; peine et la meilleure preuve est que Windows 8 est encore tout frais, n'a pas encore eu le temps de s&amp;egrave;cher (premier s&amp;eacute;chage pr&amp;eacute;vu cet &amp;eacute;t&amp;eacute; avec Windows Blue).&lt;/p&gt;
&lt;p&gt;Tout ca pour dire que c'est du grand n'importe quoi, et que ce genre de pr&amp;eacute;diction n'a aucune, mais aucune valeur ! Dire qu'il y a des "journalistes" qui reprennent ces donn&amp;eacute;es pour argumenter leurs dires...&lt;/p&gt;</description><pubDate>Fri, 29 Mar 2013 06:41:47 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/a-propos-de-previsionnistes</guid></item><item><title>Message pour Google : "Don't be evil"!</title><link>http://c2idotnet.com:80/articles/message-pour-google-don-t-be-evil</link><description>&lt;p&gt;Bon je sais, elle est facile celle-l&amp;agrave; : retourner le slogan de Google contre lui ;-)&lt;/p&gt;
&lt;p&gt;Mais c'est bel et bien ce qui est en train de se passer. On a souvent vu des editos, des articles, des r&amp;eacute;flexions de nombreuses personnes contre la position dominante de Microsoft. C'est bien car cela permet d'&amp;eacute;viter justement que ladite soci&amp;eacute;t&amp;eacute; n'en fasse "trop" &amp;agrave; sa t&amp;ecirc;te. Mais il ne faudrait surtout pas oublier Google. Si l'on est objectif, Google est actuellement bien plus pr&amp;eacute;sent dans notre vie quotidienne qu'un Microsoft ou m&amp;ecirc;me un Apple.&lt;/p&gt;
&lt;p&gt;En quelques ann&amp;eacute;es, Google a r&amp;eacute;ussi &amp;agrave; faire oublier les Altavista &amp;amp; co. Dans le monde du mobile, bien que les journalistes (et les gens en g&amp;eacute;n&amp;eacute;ral)&amp;nbsp;ne parlent que de l'iPhone, Android est en large position dominante. On dit que Microsoft n'est pas inovateur et ach&amp;egrave;te les soci&amp;eacute;t&amp;eacute;s avec leurs brevets gr&amp;acirc;ce &amp;agrave; son cash : qu'&amp;agrave; fait Google avec Youtube ?&lt;/p&gt;
&lt;p&gt;Bref, Google est devenu un gros monstre omnipr&amp;eacute;sent.&lt;/p&gt;
&lt;p&gt;Personnellement, cela ne me d&amp;eacute;range pas (trop) si ils jouent le jeu, c'est &amp;agrave; dire qu'ils continuent &amp;agrave; fournir un service de qualit&amp;eacute; (le service de messagerie de c2i.fr est chez Google). Mais le r&amp;eacute;cent "scandale" concernant le non acc&amp;egrave;s &amp;agrave; Google Maps par les Windows Phone est un signe majeur. Google peut, en quelques instants, d&amp;eacute;cider de couper son service pour tel ou tel artefact. Dans ce cas pr&amp;eacute;sent, la cible est Windows Phone qui commence &amp;agrave; faire un tout petit peu d'ombre &amp;agrave; Android.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Et Google n'aime pas ca.&lt;/li&gt;
&lt;li&gt;Google n'aime pas les t&amp;eacute;l&amp;eacute;phones Windows Phone.&lt;/li&gt;
&lt;li&gt;Google ne veut pas voir sur cette Terre des t&amp;eacute;l&amp;eacute;phones Windows Phone.&lt;/li&gt;
&lt;li&gt;Google met en oeuvre tout ses moyens pour exterminer les Windows Phone.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nous sommes dans un monde capitaliste et cette guerre concerne des entit&amp;eacute;s commerciales (ouf, j'ai eu peur que ce soit du raciste ou quelque chose dans le genre...).&lt;/p&gt;
&lt;p&gt;Cela peut faire sourire, ne pas inqui&amp;eacute;ter, mais il faut &amp;ecirc;tre vigilant, car demain, Apple pourra de nouveau faire une pub faisant voler en &amp;eacute;clat un &amp;eacute;cran diffusant une image d'un Android, elle ne sera jamais diffus&amp;eacute;e sur un Internet contr&amp;ocirc;l&amp;eacute; par Google.&lt;/p&gt;
&lt;p&gt;Edit : le site Gizm...(je ne veux pas lui faire de la pub)&amp;nbsp;a montr&amp;eacute; encore une fois la pertinence des ses infos ;-)&lt;/p&gt;</description><pubDate>Mon, 07 Jan 2013 08:25:40 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/message-pour-google-don-t-be-evil</guid></item><item><title>Sauvegarder et lire ses données dans un fichier zip</title><link>http://c2idotnet.com:80/articles/sauvegarder-et-lire-ses-donnees-dans-un-fichier-zip</link><description>&lt;p&gt;&lt;a href="http://www.c2i.fr/Media/Default/Windows-Live-Writer/e9f0414e8816_D888/ZipFile_2.png"&gt;&lt;img title="ZipFile" style="background-image: none; float: left; padding-top: 0px; padding-left: 0px; margin: 0px 10px 10px 0px; display: inline; padding-right: 0px; border: 0px;" border="0" alt="ZipFile" align="left" src="http://www.c2i.fr/Media/Default/Windows-Live-Writer/e9f0414e8816_D888/ZipFile_thumb.png" width="132" height="132" /&gt;&lt;/a&gt;Il est fr&amp;eacute;quent que l&amp;rsquo;on sauvegarde ses donn&amp;eacute;es dans un fichier. Pour effectuer cette op&amp;eacute;ration, le plus simple (si l&amp;rsquo;on est un peu fain&amp;eacute;ant) est d&amp;rsquo;utiliser l&amp;rsquo;un des s&amp;eacute;rialisateurs fourni par le Framework (le plus optimis&amp;eacute; est de cr&amp;eacute;er son propre format mais c&amp;rsquo;est une autre histoire).&lt;/p&gt;
&lt;p&gt;Ici, nous allons utiliser le s&amp;eacute;rialisateur DataContractSerializer, utilis&amp;eacute; pour les contrats WCF.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;inconv&amp;eacute;nient de ce s&amp;eacute;rialiseur, c&amp;rsquo;est qu&amp;rsquo;il ne cherche absolument pas &amp;agrave; optimiser la taille du fichier g&amp;eacute;n&amp;eacute;r&amp;eacute;, et comme le format est un format Xml, il est verbeux et donc volumineux.&lt;/p&gt;
&lt;p&gt;Vous allez me dire, avec les disques durs que l&amp;rsquo;on a actuellement, ce n&amp;rsquo;est pas vraiment un soucis. Oui, sauf que si le fichier, on veut le sauvegarder dans le RoamingFolder pour pouvoir le sauvegarder &amp;ldquo;in ze cloud&amp;rdquo;, il va falloir faire attention &amp;agrave; ce qu&amp;rsquo;il ne d&amp;eacute;passe pas les 100Ko, sinon il ne sera pas upload&amp;eacute; &amp;ldquo;in ze cloud&amp;rdquo; (propri&amp;eacute;t&amp;eacute; &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.roamingstoragequota.aspx"&gt;RoamingStorageQuota&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Donc la bonne id&amp;eacute;e, enfin celle que j&amp;rsquo;ai trouv&amp;eacute;e bonne, consiste donc &amp;agrave; zipper le contenu du fichier xml g&amp;eacute;n&amp;eacute;r&amp;eacute; par le s&amp;eacute;rialisateur.&lt;/p&gt;
&lt;p&gt;Dans mon exemple, je s&amp;eacute;rialise une &amp;eacute;num&amp;eacute;ration d&amp;rsquo;objet User :&lt;/p&gt;
&lt;div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:236748d5-2719-494c-a014-06f986a628fa" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre class="brush: c#;"&gt;private async Task WriteToZipFile()
{
    var sw = Stopwatch.StartNew();
    var file = await ApplicationData.Current.RoamingFolder
                                    .CreateFileAsync(
                                        UsersFileName,
                                        CreationCollisionOption.ReplaceExisting);

    // archivage dans le zip
    using (var fileStream = await file.OpenStreamForWriteAsync())
    {
        using (var archive = new ZipArchive(fileStream, ZipArchiveMode.Create, false))
        {
            var entry = archive.CreateEntry(UsersEntry, CompressionLevel.Fastest);
            var serializer = new DataContractSerializer(typeof (IEnumerable&amp;lt;User&amp;gt;));
            serializer.WriteObject(entry.Open(), Users);
        }
    }

    Debug.WriteLine("Sauvegarde ZIP : {0}ms", sw.ElapsedMilliseconds);
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Et je fais la m&amp;ecirc;me chose en sens inverse pour lire le contenu de ce fichier :&lt;/p&gt;
&lt;div id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:b9b42375-a0db-4c3b-b316-42ffb66d9e0f" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre class="brush: c#;"&gt;private async Task&amp;lt;IEnumerable&amp;lt;User&amp;gt;&amp;gt; ReadFromZipFile()
{
    var sw = Stopwatch.StartNew();

    var file = await ApplicationData.Current.RoamingFolder
                                    .GetFileAsync(UsersFileName);

    // archivage dans le zip
    using (var archive = new ZipArchive(await file.OpenStreamForWriteAsync(), ZipArchiveMode.Read, false))
    {
        var entry = archive.GetEntry(UsersEntry);
        var serializer = new DataContractSerializer(typeof(IEnumerable&amp;lt;User&amp;gt;));
        var result = (IEnumerable&amp;lt;User&amp;gt;) serializer.ReadObject(entry.Open());
        Debug.WriteLine("Lecture : {0}ms", sw.ElapsedMilliseconds);

        return result;
    }
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Ce n&amp;rsquo;est pas tr&amp;egrave;s compliqu&amp;eacute; et on gagne &amp;eacute;norm&amp;eacute;ment de place &lt;img class="wlEmoticon wlEmoticon-winkingsmile" style="border-style: none;" alt="Clignement d'&amp;oelig;il" src="http://www.c2i.fr/Media/Default/Windows-Live-Writer/e9f0414e8816_D888/wlEmoticon-winkingsmile_2.png" /&gt;&lt;/p&gt;
&lt;p&gt;ATTENTION : l&amp;rsquo;enregistrement, c&amp;rsquo;est-&amp;agrave;-dire la cr&amp;eacute;ation du fichier zip est long, tr&amp;egrave;s long, donc &amp;agrave; utiliser avec parcimonie et pas &amp;agrave; toutes les sauces (comme je l&amp;rsquo;avais fais dans mon code &lt;img class="wlEmoticon wlEmoticon-smilewithtongueout" style="border-style: none;" alt="Tire la langue" src="http://www.c2i.fr/Media/Default/Windows-Live-Writer/e9f0414e8816_D888/wlEmoticon-smilewithtongueout_2.png" /&gt;).&lt;/p&gt;</description><pubDate>Mon, 19 Nov 2012 14:38:11 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/sauvegarder-et-lire-ses-donnees-dans-un-fichier-zip</guid></item><item><title>Une belle épingle pour son site sous Windows 8</title><link>http://c2idotnet.com:80/articles/une-belle-epingle-pour-son-site-sous-windows-8</link><description>&lt;p&gt;Windows 8 change la fa&amp;ccedil;on de g&amp;eacute;rer ses favoris et met en avant "l'&amp;eacute;pinglage" des sites. Quand vous &amp;ecirc;tes sur un site quelconque et que vous le trouvez sympatique, avec IE 10, la meilleure (et unique sous WinRT) fa&amp;ccedil;on de faire est d'&amp;eacute;pigner le site.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/articles/2012-11/FavIE10-0.png" width="683" height="384" /&gt;&lt;/p&gt;
&lt;p&gt;Malheureusement, &amp;agrave; l'heure actuelle, on se retrouve avec des ic&amp;ocirc;nes, pardon, des tuiles, qui se ressemblent toutes, avec g&amp;eacute;n&amp;eacute;ralement un gros "e" sur forme de couleur uni. Beuark !&lt;/p&gt;
&lt;p&gt;Sous Android ou Windows Phone 7, on peut avoir des captures d'&amp;eacute;cran du site, sous Windows 8 RT, on n'a qu'un "e" : c'est au d&amp;eacute;veloppeur du site de faire le boulot.&lt;/p&gt;
&lt;p&gt;Et c'est en r&amp;eacute;alit&amp;eacute; tr&amp;egrave;s simple puisqu'il n'y a que 3 balises META &amp;agrave; ajouter &amp;agrave; votre header :&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;meta name="application-name" content="c2i.fr - Le 1er site .NET"/&amp;gt;
&amp;lt;meta name="msapplication-TileColor" content="#0072BC"/&amp;gt;
&amp;lt;meta name="msapplication-TileImage" content="http://www.c2i.fr/Media/Default/mesImages/c2iLogoIE10.png"/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Le application-name est le nom qui sera affich&amp;eacute; sur la vignette, msapplication-TileColor la couleur de fond et TileImage l&amp;rsquo;image utilis&amp;eacute;e. Cette derni&amp;egrave;re doit faire 144px * 144px et, comme vient de me signaler Fabrice Romelard, &amp;ecirc;tre forcement au format png.&lt;/p&gt;
&lt;p&gt;Et vous ne deviendrez pas ainsi un &amp;eacute;ni&amp;egrave;me raccourci sur l&amp;rsquo;&amp;eacute;cran d&amp;rsquo;accueil de Windows 8 &lt;img class="wlEmoticon wlEmoticon-winkingsmile" style="border-style: none;" alt="Clignement d'&amp;oelig;il" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Une-belle-pingle-pour-son-site-sous-Wind_95BB/wlEmoticon-winkingsmile_2.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/articles/2012-11/FavIE10.png" width="1366" height="768" /&gt;&lt;/p&gt;
&lt;p&gt;Pour les grosses fain&amp;eacute;asses, il y a m&amp;ecirc;me un site qui vous g&amp;eacute;n&amp;egrave;re le code : &lt;a title="http://www.buildmypinnedsite.com/windows8" href="http://www.buildmypinnedsite.com/windows8"&gt;http://www.buildmypinnedsite.com/windows8&lt;/a&gt;&lt;/p&gt;</description><pubDate>Wed, 14 Nov 2012 14:50:53 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/une-belle-epingle-pour-son-site-sous-windows-8</guid></item><item><title>Mettre à jour massivement une table SQL Server (1ère partie)</title><link>http://c2idotnet.com:80/articles/mettre-a-jour-massivement-une-table-sql-server-1ere-partie</link><description>&lt;p&gt;Aujourd&amp;rsquo;hui, je ne vais pas parler de Windows 8 pour une fois mais d&amp;rsquo;une probl&amp;eacute;matique que l&amp;rsquo;on peut rencontrer si l&amp;rsquo;on travaille avec des masses de donn&amp;eacute;es importantes.&lt;/p&gt;
&lt;p&gt;Imaginons donc une simple table SQL Server et une application qui r&amp;eacute;cup&amp;egrave;re des donn&amp;eacute;es et souhaite les injecter dans cette table.&lt;/p&gt;
&lt;p&gt;Jusqu&amp;rsquo;ici, rien de bien particulier. Il existe plusieurs solutions :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Parcourir les donn&amp;eacute;es une &amp;agrave; une et faire un INSERT (pas terrible au niveau perf),&lt;/li&gt;
&lt;li&gt;Faire un BulkInsert (cool au niveau perf).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Seulement le BulkInsert de SQL Server ne fait pas les mises &amp;agrave; jour. Si par hasard on a une ligne que l&amp;rsquo;on souhaite injecter qui a le m&amp;ecirc;me ID qu&amp;rsquo;une ligne existante dans la table (ID &amp;eacute;tant la cl&amp;eacute; de la table), alors le BulkInsert vous jettera comme un malpropre.&lt;/p&gt;
&lt;p&gt;NB : ce n&amp;rsquo;est pas le cas pour MySQL qui autorise, lui, l&amp;rsquo;Insert/Update dans un BulkInsert. cf &lt;a href="http://www.c2i.fr/articles/faire-du-bulk-insert-update-avec-mysql-en-.net" target="_blank"&gt;l&amp;rsquo;article suivant&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il existe toutefois une solution qui permet d&amp;rsquo;effectuer un maximum d&amp;rsquo;op&amp;eacute;ration du c&amp;ocirc;t&amp;eacute; de SQL Server, donc avec des performances importantes.&lt;/p&gt;
&lt;p&gt;La solution consiste a utiliser l&amp;rsquo;instruction &lt;a href="http://technet.microsoft.com/en-us/library/bb510625.aspx" target="_blank"&gt;MERGE de Transact-SQL&lt;/a&gt; (je crois que cette instruction n&amp;rsquo;est possible que depuis SQL Server 2008). MERGE permet de synchroniser les donn&amp;eacute;es de 2 tables. Il se charge de faire les INSERT, UPDATE et m&amp;ecirc;me les DELETE qu&amp;rsquo;il faut.&lt;/p&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, nous allons voir comment faire le BulkInsert&lt;/p&gt;
&lt;h1&gt;BulkInsert&lt;/h1&gt;
&lt;p&gt;Pour simplifier les d&amp;eacute;veloppements de nos classes Repository, nous allons cr&amp;eacute;er une classe de base qui d&amp;eacute;finie le ConnectionString :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public abstract class RepositoryBase
{
    public const string ConnectionStringKey = "MyDb";
    
    #region ctor

    protected RepositoryBase()
        : this(ConfigurationManager.ConnectionStrings[ConnectionStringKey].ConnectionString)
    {
    }

    protected RepositoryBase(string connectionString)
    {
        ConnectionString = connectionString;
    }

    #endregion
    
    /// &amp;lt;summary&amp;gt;
    /// Chaine de connection
    /// &amp;lt;/summary&amp;gt;
    public string ConnectionString { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Le ConnectionString est donc recherch&amp;eacute; dans le fichier de configuration avec la cl&amp;eacute; par d&amp;eacute;faut valant &amp;ldquo;MyDb&amp;rdquo; (why not!).&lt;/p&gt;
&lt;p&gt;Ensuite, nous allons d&amp;eacute;finir une classe abstraite de base pour effectuer le BulkInsert. C&amp;rsquo;est une classe g&amp;eacute;n&amp;eacute;rique bas&amp;eacute;e sur l&amp;rsquo;entit&amp;eacute; que l&amp;rsquo;on manipule. Elle ne poss&amp;egrave;de qu&amp;rsquo;une seule m&amp;eacute;thode qui attends comme arguments les donn&amp;eacute;es &amp;agrave; ins&amp;eacute;rer et un mappeur de propri&amp;eacute;t&amp;eacute;s. Ce dernier impl&amp;eacute;mente l&amp;rsquo;interface IRepositoryBulkInsertMapper :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public interface IRepositoryBulkInsertMapper
{
    string DestinationTableName { get; }
    IEnumerable&amp;lt;BulkInsertColumnDescription&amp;gt; GetColumnDescriptions();
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;DestinationTableName est le nom de la table ou l&amp;rsquo;on souhaite ins&amp;eacute;rer les donn&amp;eacute;es. GetColumnDescription retourne une collection de BulkInsertColumnDescription :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;/// &amp;lt;summary&amp;gt;
/// D&amp;eacute;crit une colonne utilis&amp;eacute;e pour le mapping pour le BulkInsert
/// &amp;lt;/summary&amp;gt;
public class BulkInsertColumnDescription
{
    public BulkInsertColumnDescription()
    {}

    public BulkInsertColumnDescription(string columnName, Type columnType)
    {
        ColumnName = columnName;
        ColumnType = columnType;
    }

    /// &amp;lt;summary&amp;gt;
    /// Nom de la colonne dans la base de donn&amp;eacute;es
    /// &amp;lt;/summary&amp;gt;
    public string ColumnName { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Type de la colonne
    /// &amp;lt;/summary&amp;gt;
    public Type ColumnType { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Exemple d&amp;rsquo;impl&amp;eacute;mentation de cette interface :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public class PersonBulkInsertMapper : IRepositoryBulkInsertMapper
{
    public PersonBulkInsertMapper(string destinationTableName   )
    {
        DestinationTableName = destinationTableName;
    }

    #region Implementation of IRepositoryBulkInsertMapper

    public string DestinationTableName { get; set; }

    public IEnumerable&amp;lt;BulkInsertColumnDescription&amp;gt; GetColumnDescriptions()
    {
        return new[]
            {
                new BulkInsertColumnDescription("Id", typeof (int)),
                new BulkInsertColumnDescription("Name", typeof (string)),
                new BulkInsertColumnDescription("Age", typeof (int)),
                new BulkInsertColumnDescription("CompanyId", typeof (int))
            };
    }

    #endregion
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;On voit que ce mappeur indique que les colonnes &amp;agrave; ins&amp;eacute;rer dans la table de destination sont Id, Name, Age et CompanyId.&lt;/p&gt;
&lt;p&gt;Revenons donc maintenant &amp;agrave; notre classe g&amp;eacute;n&amp;eacute;rique :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;/// &amp;lt;summary&amp;gt;
/// Classe de base qui permet le BulkInsert
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="T"&amp;gt;Entit&amp;eacute; de base&amp;lt;/typeparam&amp;gt;
public abstract class RepositoryBulkInsertBase&amp;lt;T&amp;gt; : RepositoryBase
{
    /// &amp;lt;summary&amp;gt;
    /// Effectue un BulkInsert d'une collection d'entit&amp;eacute;
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="datas"&amp;gt;Les entit&amp;eacute;s &amp;agrave; ins&amp;eacute;rer&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="mapper"&amp;gt;Le mapper entre les colonnes et les valeurs&amp;lt;/param&amp;gt;
    public void BulkInsert(IEnumerable&amp;lt;T&amp;gt; datas, IRepositoryBulkInsertMapper mapper)
    {
        using (
            var bulkCopy = new SqlBulkCopy(
                ConnectionString,
                SqlBulkCopyOptions.TableLock |
                SqlBulkCopyOptions.CheckConstraints |
                SqlBulkCopyOptions.FireTriggers))
        {
            // cr&amp;eacute;ation de la DataTable et du mapping
            var table = new DataTable();
            foreach (var description in mapper.GetColumnDescriptions())
            {
                // ajout de la colonne
                table.Columns.Add(new DataColumn(description.ColumnName, description.ColumnType));
                // ajout du mapping dans le bulkCopy
                bulkCopy.ColumnMappings.Add(description.ColumnName, description.ColumnName);
            }

            // table ou l'on souhaite ins&amp;eacute;rer les donn&amp;eacute;es
            bulkCopy.DestinationTableName = mapper.DestinationTableName;

            // remplissage de la DataTable avec les donn&amp;eacute;es
            foreach (var data in datas)
            {
                var columnValues = new List&amp;lt;object&amp;gt;();

                foreach (DataColumn column in table.Columns)
                {
                    columnValues.Add(typeof (T).GetProperty(column.ColumnName).GetValue(data, null));
                }
                table.Rows.Add(columnValues.ToArray());
            }

            // envoi du BulkCopy &amp;agrave; SQL Server
            bulkCopy.WriteToServer(table);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Cette m&amp;eacute;thode ne fait que cr&amp;eacute;er dans un premier temps la structure de la DataTable gr&amp;acirc;ce aux ColumnDescriptions et rempli cette DataTable avec nos donn&amp;eacute;es.&lt;/p&gt;
&lt;p&gt;Impl&amp;eacute;mentons maintenant cette classe abstraite (oui, il n&amp;rsquo;y a aucune ligne de code &lt;img style="border-style: none;" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d'&amp;oelig;il" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/e7c42ae3d7c6_A577/wlEmoticon-winkingsmile_2.png" /&gt;) :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public class PersonBulkInsertRepository : RepositoryBulkInsertBase&amp;lt;Person&amp;gt;
{}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Et pour l&amp;rsquo;utiliser :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;var rep = new PersonBulkInsertRepository();
rep.BulkInsert(persons, new PersonBulkInsertMapper("Persons"));&lt;/pre&gt;
&lt;pre class="brush: csharp;"&gt;&lt;/pre&gt;
&lt;p&gt;Si l'on sait que cette classe utilisera m&amp;ecirc;me toujours la m&amp;ecirc;me interface de mapping, on peut lui ajouter une m&amp;eacute;thode simplifiant son utilisation :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public class PersonBulkInsertRepository : RepositoryBulkInsertBase&amp;lt;Person&amp;gt;
{
    public void BulkInsert(IEnumerable&amp;lt;Person&amp;gt; datas)
    {
        BulkInsert(datas, new PersonBulkInsertMapper("Persons"));
    }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Moralit&amp;eacute;, l&amp;rsquo;insertion massive de donn&amp;eacute;es dans la table devient encore plus simple :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;var rep = new PersonBulkInsertRepository();
rep.BulkInsert(persons);
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Maintenant que nous savons faire du simple BulkInsert, nous verrons dans &lt;a href="http://www.c2i.fr/articles/mettre-a-jour-massivement-une-table-sql-server-2-eme-partie"&gt;le prochain article&lt;/a&gt; comment l&amp;rsquo;utiliser pour faire du Merge.&lt;/p&gt;</description><pubDate>Tue, 13 Nov 2012 16:54:09 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/mettre-a-jour-massivement-une-table-sql-server-1ere-partie</guid></item><item><title>Mettre à jour massivement une table SQL Server (2ème partie)</title><link>http://c2idotnet.com:80/articles/mettre-a-jour-massivement-une-table-sql-server-2-eme-partie</link><description>&lt;p&gt;&lt;a href="http://www.c2i.fr/articles/mettre-a-jour-massivement-une-table-sql-server-1ere-partie"&gt;Dans le premier article&lt;/a&gt;, je vous indiquais comment faire du BulkInsert avec SQL Server. Dans cette deuxi&amp;egrave;me partie, nous allons voir comment utiliser l&amp;rsquo;instruction MERGE pour faire de la mise &amp;agrave; jour massive. On avait le sch&amp;eacute;ma de classes suivant :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Mettre--jour-massivement-une-table-SQL-S_F413/BulkInsert_2.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="BulkInsert" border="0" alt="BulkInsert" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Mettre--jour-massivement-une-table-SQL-S_F413/BulkInsert_thumb.png" width="633" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notre but va donc &amp;ecirc;tre de pouvoir faire de la mise &amp;agrave; jour massive. Nous avons besoin pour cela d&amp;rsquo;uen table temporaire poss&amp;eacute;dant la m&amp;ecirc;me structure que la table cible. Puis, nous allons proc&amp;eacute;der ainsi :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Vider la table temporaire (par s&amp;eacute;curit&amp;eacute;),&lt;/li&gt;
&lt;li&gt;Faire un BulkInsert des donn&amp;eacute;es dans la table temporaire,&lt;/li&gt;
&lt;li&gt;Faire un Merge entre la table temporaire et la table cible,&lt;/li&gt;
&lt;li&gt;Vider la table temporaire (la madame elle aime bien faire le m&amp;eacute;nage&amp;hellip;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Donc dans un premier temps, d&amp;eacute;finissons une classe abstraite impl&amp;eacute;mentant l&amp;rsquo;op&amp;eacute;ration de Merge :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;/// &amp;lt;summary&amp;gt;
/// Classe de base qui permet de faire le Merge
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="T"&amp;gt;Entit&amp;eacute;&amp;lt;/typeparam&amp;gt;
public abstract class RepositoryMergeBase&amp;lt;T&amp;gt; : RepositoryBulkInsertBase&amp;lt;T&amp;gt;
{
    /// &amp;lt;summary&amp;gt;
    /// Requ&amp;ecirc;te SQL pour le Merge &amp;agrave; d&amp;eacute;finir dans les classes d&amp;eacute;rivantes
    /// &amp;lt;/summary&amp;gt;
    protected abstract string SqlMerge { get; }

    /// &amp;lt;summary&amp;gt;
    /// Nom de la table temporaire utilis&amp;eacute;e pour le Merge dans les classes d&amp;eacute;rivantes
    /// &amp;lt;/summary&amp;gt;
    protected abstract string TempTableName { get; }

    protected virtual void CleanTempTable()
    {
        using (var connection = new SqlConnection(ConnectionString))
        {
            using (var command = new SqlCommand(string.Format("DELETE FROM {0}", TempTableName), connection))
            {
                connection.Open();

                command.ExecuteNonQuery();
            }
        }
    }

    public SynchronizationResult Merge(IEnumerable&amp;lt;T&amp;gt; datas, IRepositoryBulkInsertMapper mapper)
    {
        if (string.IsNullOrEmpty(SqlMerge))
            throw new InvalidOperationException("SqlMerge n'a pas &amp;eacute;t&amp;eacute; d&amp;eacute;fini");

        if (string.IsNullOrEmpty(TempTableName))
            throw new InvalidOperationException("TempTableName n'a pas &amp;eacute;t&amp;eacute; d&amp;eacute;fini");

        // on vide la table temporaire avant l'import (au cas ou)
        CleanTempTable();

        // importation massive des donn&amp;eacute;es dans la table temporaire
        BulkInsert(datas.ToList(), mapper);

        // ex&amp;eacute;cution du Merge entre la table temporaire et la table cible
        var result = Merge();

        // on vide la table temporaire
        CleanTempTable();

        return result;
    }

    #region private methods
    /// &amp;lt;summary&amp;gt;
    /// Effectue le merge
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    private SynchronizationResult Merge()
    {
        var result = new SynchronizationResult();
        using (var connection = new SqlConnection(ConnectionString))
        {
            // SqlMerge est l'instruction Transact-SQL avec MERGE
            using (var command = new SqlCommand(SqlMerge, connection))
            {
                connection.Open();

                // l'instruction Merge retourne le nombre d'insert/update/delete effectu&amp;eacute;
                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        switch ((string)reader["$action"])
                        {
                            case "INSERT":
                                result.Inserted++;
                                break;
                            case "UPDATE":
                                result.Updated++;
                                break;
                            case "DELETE":
                                result.Deleted++;
                                break;
                            default:
                                throw new NotImplementedException(
                                    "Erreur dans le merge : " +
                                    (string) reader["$action"]);
                        }
                    }

                    return result;
                }
            }
        }
    }
    #endregion

}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Cette classe abstraite demande aux classes qui en d&amp;eacute;rivent de d&amp;eacute;finir la propri&amp;eacute;t&amp;eacute; SqlMerge et TempTableName. SqlMerge est l&amp;rsquo;instruction Transact-SQL (voir plus loin) et TempTableName est le nom de la table temporaire.&lt;/p&gt;
&lt;p&gt;Dans la m&amp;eacute;thode Merge, on effectue les t&amp;acirc;ches d&amp;eacute;crites plus haut : vidage, bulkInsert dans la table temporaire, merge et vidage (again). En proc&amp;eacute;dant ainsi, les donn&amp;eacute;es ne sont envoy&amp;eacute;es qu&amp;rsquo;une seule fois massivement &amp;agrave; SQL Server, et c&amp;rsquo;est lui qui fait tout le travail. Les autres aller-retour avec le serveur ne sont que des petites instructions SQL, donc on a une rapidit&amp;eacute; optimis&amp;eacute;e.&lt;/p&gt;
&lt;p&gt;Le plus compliqu&amp;eacute; (si l&amp;rsquo;on peut dire) consiste &amp;agrave; impl&amp;eacute;menter cette classe, c&amp;rsquo;est-&amp;agrave;-dire surtout &amp;agrave; d&amp;eacute;finir l&amp;rsquo;instruction Merge. Voyons pour notre exemple son impl&amp;eacute;mentation :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public class PersonRepository : RepositoryMergeBase&amp;lt;Person&amp;gt;
{
    public SynchronizationResult Merge(IEnumerable&amp;lt;Person&amp;gt; rows)
    {
        return Merge(rows, new PersonBulkInsertMapper(TempTableName));
    }

    #region Overrides of RepositoryMergeBase&amp;lt;Person&amp;gt;
    /// &amp;lt;summary&amp;gt;
    /// Nom de la table temporaire utilis&amp;eacute;e pour le Merge
    /// &amp;lt;/summary&amp;gt;
    protected override string TempTableName
    {
        get { return "Persons_Temp"; }
    }

    /// &amp;lt;summary&amp;gt;
    /// Requ&amp;ecirc;te SQL pour le Merge &amp;agrave; d&amp;eacute;finir dans les classes d&amp;eacute;rivantes
    /// &amp;lt;/summary&amp;gt;
    protected override string SqlMerge
    {
        get
        {
            return @"
MERGE Persons AS target
USING Persons_Temp AS source
ON (target.Id = source.Id)
WHEN MATCHED THEN
 UPDATE
      SET
           target.Name = source.Name,
           target.Age = source.Age,
           target.CompanyId = source.CompanyId
WHEN NOT MATCHED BY TARGET THEN
 INSERT (Name, Age, CompanyId)
 VALUES (source.Name, source.Age, source.CompanyId)
OUTPUT
 $action;
";
        }
    }
    #endregion
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Vous voyez que l&amp;rsquo;instruction Merge est d&amp;eacute;compos&amp;eacute;e en trois parties :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;L&amp;rsquo;instruction On d&amp;eacute;finit quand 2 enregistrements sont consid&amp;eacute;r&amp;eacute;s comme &amp;eacute;gaux&lt;/li&gt;
&lt;li&gt;L&amp;rsquo;instruction Update &amp;agrave; utiliser quand On est v&amp;eacute;rifi&amp;eacute;&lt;/li&gt;
&lt;li&gt;L&amp;rsquo;instruction Insert &amp;agrave; utiliser quand On n&amp;rsquo;est pas v&amp;eacute;rifi&amp;eacute;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Merge nous renvoi &amp;eacute;galement un tableau de r&amp;eacute;sultat avec une colonne contenant l&amp;rsquo;action qu&amp;rsquo;il a effectu&amp;eacute;. On sait ainsi s&amp;rsquo;il a effectu&amp;eacute; un insert, update ou delete (NB : dans cet exemple, nous n&amp;rsquo;effectuons pas de Delete, juste du Insert/Update). On retourne cette information sous la forme d&amp;rsquo;un objet de type SynchronizationResult.&lt;/p&gt;
&lt;p&gt;Pour utiliser cette classe, cela devient un jeu d&amp;rsquo;enfant :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;var repository = new PersonRepository();

var result = repository.Merge(persons);

Console.WriteLine(
    "Inserted = {0}, Updated = {1}, Deleted = {2}", 
    result.Inserted, 
    result.Updated, 
    result.Deleted);
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;R&amp;eacute;sumons&lt;/h1&gt;
&lt;p&gt;&lt;a href="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Mettre--jour-massivement-une-table-SQL-S_F413/ClassDiagram1_2.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="ClassDiagram1" border="0" alt="ClassDiagram1" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Mettre--jour-massivement-une-table-SQL-S_F413/ClassDiagram1_thumb.png" width="698" height="772" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pour faire notre Merge, nous n&amp;rsquo;avons besoin que de d&amp;eacute;finir SqlMerge et TempTableName dans la classe d&amp;eacute;riv&amp;eacute;e.&lt;/p&gt;
&lt;p&gt;Simple non ?&lt;/p&gt;
&lt;p&gt;&lt;a href="https://skydrive.live.com/redir?resid=BC9DE0EB6CF2FF4E!23197&amp;amp;authkey=!AGtLsv8bFGceMmQ" target="_blank"&gt;T&amp;eacute;l&amp;eacute;chargez le source de cet exemple&lt;/a&gt;.&lt;/p&gt;</description><pubDate>Tue, 13 Nov 2012 16:52:55 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/mettre-a-jour-massivement-une-table-sql-server-2-eme-partie</guid></item><item><title>'Un jour, une plante' pour Windows 8</title><link>http://c2idotnet.com:80/articles/un-jour-une-plante-pour-windows-8</link><description>&lt;p&gt;"Un jour, une plante" est une application pour Windows 8 qui&amp;nbsp;vous propose de lire quotidiennement une fiche sur une plante de votre jardin, de votre potager, &amp;eacute;crite par un sp&amp;eacute;cialiste fran&amp;ccedil;ais reconnu dans le domaine, Pierrick Eberhard.&lt;/p&gt;
&lt;p&gt;&lt;iframe height="480" src="http://www.youtube.com/embed/C_ldq_K9wPk" frameborder="0" width="853" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://goo.gl/BWz9L"&gt;T&amp;eacute;l&amp;eacute;chargez l'application sur le Windows Store&lt;/a&gt;&lt;/p&gt;</description><pubDate>Fri, 02 Nov 2012 09:35:24 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/un-jour-une-plante-pour-windows-8</guid></item><item><title>Homéo Zen pour Windows 8</title><link>http://c2idotnet.com:80/articles/homeo-zen-pour-windows-8</link><description>&lt;p&gt;"Hom&amp;eacute;o Zen", une application Windows 8 de c2i.fr,&amp;nbsp;vous propose quotidiennement une dose de positif, d&amp;rsquo;attitude zen pour profiter au mieux de votre journ&amp;eacute;e.&lt;/p&gt;
&lt;p&gt;&lt;iframe height="480" src="http://www.youtube.com/embed/TlQ0ZCa092Y" frameborder="0" width="853" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Pour en savoir plus sur cette application : &lt;a href="http://www.c2i.fr/HomeoZen"&gt;http://www.c2i.fr/HomeoZen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://goo.gl/sKcgI"&gt;T&amp;eacute;l&amp;eacute;chargement sur le Windows Store&lt;/a&gt;&lt;/p&gt;</description><pubDate>Fri, 02 Nov 2012 09:31:34 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/homeo-zen-pour-windows-8</guid></item><item><title>Créer un lien vers le Windows Store dans votre application</title><link>http://c2idotnet.com:80/articles/creer-un-lien-vers-le-windows-store-dans-votre-application</link><description>&lt;h2&gt;Une petite astuce ce vendredi matin.&lt;/h2&gt;
&lt;p&gt;Il se peut que dans votre application vous ayez besoin d'int&amp;eacute;ragir avec le Windows Store. Voici quelques exemples :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inciter votre utilisateur &amp;agrave; poster un commentaire sur votre application,&lt;/li&gt;
&lt;li&gt;Ouvrir le Windows Store sur une autre de vos applications,&lt;/li&gt;
&lt;li&gt;Ouvrir le Windows Store vers une recherche particuli&amp;egrave;re.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Concernant le premier exemple, je ne suis pas sur que si le "bouton" ou le truc qui permet d'effectuer cette action est trop voyant, votre application passe la certification. Veillez donc &amp;agrave; quelle soit discr&amp;egrave;te ou plut&amp;ocirc;t logique.&lt;/p&gt;
&lt;p&gt;En revanche, pour les deux autres, si vous avez d'autres applications, c'est fortement recommand&amp;eacute; pour cr&amp;eacute;er une synergie entre vos applis. (si un utilisateur est content de votre application, il y a de fortes chances qu'ils d&amp;eacute;sirent ne serait ce essayer vos autres applications). Ci-dessous un exemple d'&amp;eacute;cran "A propos de..." :&lt;/p&gt;
&lt;p&gt;&lt;img width="640" height="360" alt="" src="/Media/Default/BlogPost/articles/LinkStore.png" /&gt;&lt;/p&gt;
&lt;p&gt;Le bouton D&amp;eacute;couvrez 'Un jour, Une plante' ouvre le Windows Store directement sur cette "fantastique" application, le second effectue une recherche sur le store sur toutes les applications de c2i.fr.&lt;/p&gt;
&lt;p&gt;Pour proc&amp;eacute;der, rien de plus simple, il suffit de cr&amp;eacute;er une Uri conforme au protocole de lien du Windows Store. Toute Uri vers le Store est pr&amp;eacute;fix&amp;eacute;e par : &lt;strong&gt;ms-windows-store:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ensuite, elle est suivi par l'action que vous souhaitez effectuer :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PDP : ouvrir la page d'une application sp&amp;eacute;cifique,&lt;/li&gt;
&lt;li&gt;Updates : ouvre le page des mises &amp;agrave; jour de toutes vos applications,&lt;/li&gt;
&lt;li&gt;Search : ouvre la page de recherche du Store,&lt;/li&gt;
&lt;li&gt;Review : ouvre la page de commentaire d'une application sp&amp;eacute;cifique (&amp;eacute;crivez un commentaire ou modifiez un commentaire si vous l'avez d&amp;eacute;j&amp;agrave; saisi). Attention : action non document&amp;eacute;e ;-)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enfin, certaines actions attendent un param&amp;egrave;tre :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PDP et&amp;nbsp;Review&amp;nbsp;attendent le Package Family Name,&lt;/li&gt;
&lt;li&gt;Search la requ&amp;ecirc;te &amp;agrave; effectuer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Mise en oeuvre d'un lien vers une application sp&amp;eacute;cifique&lt;/h2&gt;
&lt;p&gt;Ainsi, pour cr&amp;eacute;er un lien vers mon application "Hom&amp;eacute;o Zen", j'ouvre son package manifeste et je note son Package Family Name :&lt;/p&gt;
&lt;p&gt;&lt;img width="512" height="397" alt="" src="/Media/Default/BlogPost/articles/creer-un-lien-vers-le-windows-store-dans-votre-application/LinkStore1.PNG" /&gt;&lt;/p&gt;
&lt;p&gt;Dans mon autre application, pour ouvrir le store vers cette fantastique application (bon, si &lt;strong&gt;LA&lt;/strong&gt;, vous avez toujours pas compris qu'il faut la t&amp;eacute;l&amp;eacute;charger et l'installer, je ne sais plus quoi faire ! Si, le lien : pour &lt;a href="http://apps.microsoft.com/webpdp/fr-FR/app/un-jour-une-plante/8b494de4-10f9-4ede-806b-e9e0a7d31ce2"&gt;Un jour, Une plante&lt;/a&gt;, et pour &lt;a href="http://apps.microsoft.com/webpdp/fr-FR/app/homeo-zen/017ab8e2-10f3-4e36-8829-421716b3426f"&gt;Hom&amp;eacute;o Zen&lt;/a&gt;), il suffit de cr&amp;eacute;er l'Uri :&lt;/p&gt;
&lt;p&gt;ms-windows-store:PDP?PFN=c2i.fr.Unjouruneplante_xxxxxxxxx&lt;/p&gt;
&lt;p&gt;Et pour la lancer dans votre application, un simple : await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-windows-store:PDP?PFN=c2i.fr.Unjouruneplante_xxxxxxxxx"));&lt;/p&gt;
&lt;h2&gt;Lien vers une recherche&lt;/h2&gt;
&lt;p&gt;Pour la recherche, c'est aussi simple avec cette fois le param&amp;egrave;tre query. Exemple pour les applications de c2i.fr, l'uri est (si vous &amp;ecirc;tes sous IE10, testez le lien pour voir) :&lt;/p&gt;
&lt;p&gt;&lt;a href="ms-windows-store:SEARCH?query=c2i.fr"&gt;ms-windows-store:SEARCH?query=c2i.fr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Oui, en cliquant dessus dans IE10, le browser de Microsoft ouvre bien lui m&amp;ecirc;me le Windows Store (une bonne fa&amp;ccedil;on pour tester le r&amp;eacute;sultat de votre recherche).&lt;/p&gt;
&lt;p&gt;&lt;img width="850" height="403" alt="" src="/Media/Default/BlogPost/articles/creer-un-lien-vers-le-windows-store-dans-votre-application/LinkStore2.PNG" /&gt;&lt;/p&gt;
&lt;h2&gt;Lien vers le commentaire&lt;/h2&gt;
&lt;p&gt;Tout comme pour l'ouverture de la page de l'application, l'action REVIEW attend le Package Family Name :&lt;/p&gt;
&lt;p&gt;ms-windows-store:REVIEW?PFN=c2i.fr.Unjouruneplante_xxxxxxxxx&lt;/p&gt;
&lt;p&gt;Encore une fois, cette action est non document&amp;eacute;e et son utilisation est &amp;agrave; prendre avec des pincettes.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Si vous d&amp;eacute;veloppez plusieurs applications pour Windows Store, il est important de cr&amp;eacute;er cette synergie entre vos applications, donc n'h&amp;eacute;sitez pas &amp;agrave; int&amp;eacute;ragir avec le Windows Store, vous augmenterez vos t&amp;eacute;l&amp;eacute;chargements.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Sat, 29 Sep 2012 01:00:57 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/creer-un-lien-vers-le-windows-store-dans-votre-application</guid></item><item><title>CodeS-SourceS rejoint CommentCaMarche.net : retour en arrière...</title><link>http://c2idotnet.com:80/articles/codes-sources-rejoint-commentcamarche.net.-retour-en-arriere</link><description>&lt;p&gt;Hier, petit retour en arri&amp;egrave;re...&lt;/p&gt;
&lt;p&gt;En consultant Google+ hier avant de prendre l'avion, je tombe sur &lt;a href="https://plus.google.com/u/0/104693319637724910181/posts/iHfjfsyuWaN"&gt;une publication de Pierre Tran&lt;/a&gt; (le&amp;nbsp;geek vampire ;-))&amp;nbsp;qui pointe vers la page suivante :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.codes-sources.com/nix/archive/2012/09/27/une-page-se-tourne-l-rsquo-aventure-continue.aspx"&gt;L'histoire fabuleuse de CodeS-SourceS.com qui rejoint le groupe CommentCaMarche.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Oula boudiou, ca nous rajeunit pas tout ca ! Apr&amp;egrave;s une soir&amp;eacute;e avec &lt;a href="http://www.asp-php.net/redaction.php?idredac=17"&gt;Redo&lt;/a&gt; lundi, Nix qui revient dans l'avant sc&amp;egrave;ne de l'actualit&amp;eacute; ce jeudi&amp;nbsp;!&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/actualites/2012-09/vbFrance.JPG" width="600" height="358" /&gt;&lt;/p&gt;
&lt;p&gt;Et pourquoi pas pro.wanadoo.fr/c2i, ASP-Magazine.com, Asp-php.net, TechHeadBrothers.com (Laurent va me tuer, il est pas mort son site&amp;nbsp;;-)), Dotnetguru.org, Dotnet-project.com&amp;nbsp;et j'en passe...&lt;/p&gt;
&lt;p&gt;Tous ont &amp;eacute;t&amp;eacute; des acteurs majeurs des d&amp;eacute;veloppeurs du&amp;nbsp;web francophone fin des ann&amp;eacute;es 90, d&amp;eacute;but des ann&amp;eacute;es 2000.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://www.c2i.fr/Media/Default/BlogPost/actualites/2012-09/vbFrance2.JPG" width="354" height="287" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/actualites/2012-09/vbFrance3.JPG" width="600" height="249" /&gt;&lt;/p&gt;
&lt;p&gt;(tiens, y'a toujours une pub pour Project Hoshimi ;-))&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/actualites/2012-09/vbFrance4.JPG" width="600" height="243" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/actualites/2012-09/asp-php.jpg" width="600" height="278" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Comme le dit (ou sous-entend Nico), pratiquement la majorit&amp;eacute; de ces acteurs ont &amp;eacute;t&amp;eacute; Microsoft MVP, que ce soit les fondateurs de ces sites que les membres les plus actifs de ces communaut&amp;eacute;s (d'ailleurs, j'aimerais bien qu'on me dise quelles sont les communaut&amp;eacute;s de d&amp;eacute;veloppeurs .NET&amp;nbsp;aujourd'hui ? A part Developpez.com, j'ai peur que les plus actifs ne soient les &amp;eacute;vang&amp;eacute;listes de MS - ce qui en dirait long -&amp;nbsp;mais je me trompe peut-&amp;ecirc;tre).&lt;/p&gt;
&lt;p&gt;Ceci dit, Nico a lanc&amp;eacute; son site perso &amp;agrave; peu pr&amp;egrave;s &amp;agrave; la m&amp;ecirc;me p&amp;eacute;riode que moi (je dirais plut&amp;ocirc;t apr&amp;egrave;s mais je ne voudrais pas le vexer, il est succeptible ;-)) et que de chemin parcouru.&lt;/p&gt;
&lt;p&gt;VBFrance puis CodeS-Sources puis l'industrialisation de CodeS-Sources (dans le bon sens), son d&amp;eacute;part "hollywoodien" du programme MVP, et la fondation de Magma Mobile.&lt;/p&gt;
&lt;p&gt;BRAVO NICO !&lt;/p&gt;
&lt;p&gt;Bon et maintenant j'ai envi de dire :&amp;nbsp;quoi de neuf docteur ? what's next ?&lt;/p&gt;
&lt;p&gt;NB : si j'ai oubli&amp;eacute; des sites, d&amp;eacute;sol&amp;eacute; ce n'est pas voulu, c'est juste Alzeihmer qui me gu&amp;ecirc;te. N'h&amp;eacute;sitez pas &amp;agrave; le signaler.&lt;/p&gt;</description><pubDate>Fri, 28 Sep 2012 07:41:06 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/codes-sources-rejoint-commentcamarche.net.-retour-en-arriere</guid></item><item><title>Tester l'existence d'un fichier avec les API Win32 pour WinRT</title><link>http://c2idotnet.com:80/articles/tester-l-existence-d-un-fichier-avec-les-api-win32-pour-winrt</link><description>&lt;p&gt;C&amp;rsquo;est un sujet qui revient p&amp;eacute;riodiquement quand vous d&amp;eacute;veloppez une application pour Metro : comment savoir si un fichier existe d&amp;eacute;j&amp;agrave; ?&lt;/p&gt;
&lt;p&gt;Malheureusement, les API de WinRT ne proposent pas par d&amp;eacute;faut de m&amp;eacute;thode comme FileExists du Framework 1.0 de .NET ! Pour l&amp;rsquo;instant, je n&amp;rsquo;ai trouv&amp;eacute; que deux possibilit&amp;eacute;s.&lt;/p&gt;
&lt;h1&gt;Par it&amp;eacute;ration&lt;/h1&gt;
&lt;p&gt;On effectue une it&amp;eacute;ration sur l&amp;rsquo;ensemble des fichiers du StorageFolder et d&amp;egrave;s qu&amp;rsquo;on a trouv&amp;eacute; le fichier recherch&amp;eacute;, on retourne true, sinon on retourne false. Cette m&amp;eacute;thode a &amp;eacute;t&amp;eacute; expos&amp;eacute;e par &lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2012/07/04/tips-and-tricks-for-c-metro-developers-the-fileexistsasync-method.aspx" target="_blank"&gt;David Catuhe sur son blog&lt;/a&gt; et se r&amp;eacute;sume ainsi :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public static class StorageFolderExtensions
{
    public static async Task&amp;lt;bool&amp;gt; FileExistsAsync(this StorageFolder folder, string name)
    {
        var files = await folder.GetFilesAsync();

        return files.Any(f =&amp;gt; f.Name == name);
    }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;inconv&amp;eacute;nient de cette m&amp;eacute;thode est que si votre dossier contient de nombreux fichiers, elle est &amp;ldquo;lente&amp;rdquo;.&lt;/p&gt;
&lt;h1&gt;La m&amp;eacute;thode brutale&lt;/h1&gt;
&lt;p&gt;Cette derni&amp;egrave;re essaye d&amp;rsquo;obtenir une r&amp;eacute;f&amp;eacute;rence vers le fichier et si il n&amp;rsquo;existe pas, une exception est d&amp;eacute;clench&amp;eacute;e. Il suffit donc de mettre tout cela dans un try/catch :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public static class StorageFolderExtensions
{
    public static async Task&amp;lt;bool&amp;gt; FileExistsAsync(this StorageFolder folder, string name)
    {
        try
        {
            await folder.GetFileAsync(name);
            return true;
        }
        catch
        {
            return false;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;int&amp;eacute;r&amp;ecirc;t est que cette m&amp;eacute;thode est plus rapide mais qu&amp;rsquo;elle est bas&amp;eacute;e sur le d&amp;eacute;clenchement d&amp;rsquo;une exception, ce qui n&amp;rsquo;est pas du meilleur effet !&lt;/p&gt;
&lt;p&gt;Il y a tout de m&amp;ecirc;me une autre solution : l&amp;rsquo;utilisation des API Win32&lt;/p&gt;
&lt;h1&gt;La m&amp;eacute;thode Win32&lt;/h1&gt;
&lt;p&gt;Depuis que je fais du .NET, j&amp;rsquo;avoue que je n&amp;rsquo;ai jamais plus utilis&amp;eacute; les API Win32 comme on le faisait couramment avec Visual Basic 4-6. C&amp;rsquo;est donc avec une larme &amp;agrave; l&amp;rsquo;oeil (souvenir, souvenir) que je me suis replong&amp;eacute; dedans. Avec Metro, vous avez acc&amp;egrave;s &amp;agrave; une liste d&amp;rsquo;API Win32 tri&amp;eacute;s sur le volet par Microsoft. Parmi celles-&amp;ccedil;i, il y en a une qui nous int&amp;eacute;resse plus particuli&amp;egrave;rement ici : GetFieAttributesEx.&lt;/p&gt;
&lt;p&gt;Nous allons donc cr&amp;eacute;er une classe NativeOperations ou nous allons d&amp;eacute;clarer l&amp;rsquo;API et les structures qui sont n&amp;eacute;cessaires :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;internal class NativeOperations
 {
     // ReSharper disable InconsistentNaming
     /// &amp;lt;summary&amp;gt;
     /// La d&amp;eacute;claration de l'API GetFileAttributesEx
     /// &amp;lt;/summary&amp;gt;
     /// &amp;lt;param name="lpFileName"&amp;gt;Le nom du fichier recherch&amp;eacute;&amp;lt;/param&amp;gt;
     /// &amp;lt;param name="fInfoLevelId"&amp;gt;Quelles types d'info on recherche&amp;lt;/param&amp;gt;
     /// &amp;lt;param name="lpFileInformation"&amp;gt;Structure contenant les informations une fois l'API appel&amp;eacute;e&amp;lt;/param&amp;gt;
     /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
     [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
     [return: MarshalAs(UnmanagedType.Bool)]
     public static extern bool GetFileAttributesEx(
         string lpFileName,
         GET_FILEEX_INFO_LEVELS fInfoLevelId,
         out WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);

     /// &amp;lt;summary&amp;gt;
     /// Type d'infos recherch&amp;eacute;es
     /// &amp;lt;/summary&amp;gt;
     public enum GET_FILEEX_INFO_LEVELS
     {
         /// &amp;lt;summary&amp;gt;
         /// C'est la seule valeur autoris&amp;eacute;e avec WinRT
         /// &amp;lt;/summary&amp;gt;
         GetFileExInfoStandard,
         /// &amp;lt;summary&amp;gt;
         /// Ne fonctionne pas sous WinRT =&amp;gt; marqu&amp;eacute; Obsolete
         /// &amp;lt;/summary&amp;gt;
         [Obsolete]
         GetFileExMaxInfoLevel
     }

     /// &amp;lt;summary&amp;gt;
     /// Structure contenant les informations sur le fichier
     /// &amp;lt;/summary&amp;gt;
     [StructLayout(LayoutKind.Sequential)]
     public struct WIN32_FILE_ATTRIBUTE_DATA
     {
         public FileAttributes dwFileAttributes;
         public FILETIME ftCreationTime;
         public FILETIME ftLastAccessTime;
         public FILETIME ftLastWriteTime;
         public uint nFileSizeHigh;
         public uint nFileSizeLow;
     }

     // quelques valeurs d'erreurs succeptibles d'arriver
     private const int ERROR_FILE_NOT_FOUND = 2;
     private const int ERROR_PATH_NOT_FOUND = 3;
     private const int ERROR_ACCESS_DENIED = 5;

&lt;/pre&gt;
&lt;p&gt;Maintenant, il ne nous reste plus qu&amp;rsquo;&amp;agrave; utiliser cette API :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public static bool FileExist(string fileName)
{
WIN32_FILE_ATTRIBUTE_DATA fileData;
if (GetFileAttributesEx(fileName, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, out fileData))
    return true;

// r&amp;eacute;cup&amp;eacute;ration de la derni&amp;egrave;re erreur (in the same thread of course ;-))
var lastError = Marshal.GetLastWin32Error();
if (lastError == ERROR_FILE_NOT_FOUND || lastError == ERROR_PATH_NOT_FOUND) return false;
// si c'est pas un fichier non trouv&amp;eacute;, on lance une exception
if (lastError == ERROR_ACCESS_DENIED)
    throw new SecurityAccessDeniedException("Acc&amp;egrave;s interdit");

throw new InvalidOperationException(string.Format("Erreur pendant l'acc&amp;egrave;s au fichier {0}, code {1}", fileName, lastError));
}
&lt;/pre&gt;
&lt;p&gt;Et ca marche, sans exception, sans it&amp;eacute;ration, et c&amp;rsquo;est tr&amp;egrave;s rapide.&lt;/p&gt;
&lt;h1&gt;Limitations de cette d&amp;eacute;marche&lt;/h1&gt;
&lt;p&gt;Il y a une grosse limitation &amp;agrave; cette d&amp;eacute;marche : elle ne fonctionne qu&amp;rsquo;avec le local storage ! M&amp;ecirc;me si vous d&amp;eacute;clarez que vous avez le droit d&amp;rsquo;acc&amp;eacute;der au dossier des Images &amp;amp; co, il refusera d&amp;rsquo;y acc&amp;eacute;der (AccessDeniedException). Donc cela va tr&amp;egrave;s bien si vous recherchez des fichiers dans votre local Storage, mais vous pouvez la mettre &amp;agrave; la poubelle si vous voulez rechercher dans un autre dossier (sniff, sniff).&lt;/p&gt;
&lt;p&gt;En revanche, c&amp;ocirc;t&amp;eacute; performances, il n&amp;rsquo;y a pas photo. J&amp;rsquo;ai effectu&amp;eacute; un test (IMPORTANT : en mode Release) sur un r&amp;eacute;pertoire contenant plus de 600 fichiers. J&amp;rsquo;effectue une recherche d&amp;rsquo;existence de chacun des fichiers puis sur des noms de fichiers dont je sais pertinemment qu&amp;rsquo;ils n&amp;rsquo;existent pas. R&amp;eacute;sultat : je vais entre 5 et 10 fois plus vite avec les API Win32.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Il n&amp;rsquo;y a donc pas photo : si vous devez chercher r&amp;eacute;guli&amp;egrave;rement dans votre local Storage, utilisez cette m&amp;eacute;thode. En revanche, elle ne vous sera d&amp;rsquo;aucunes utilit&amp;eacute;s ailleurs. Dommage !&lt;/p&gt;
&lt;p&gt;En esp&amp;eacute;rant que la version finale des API WinRT comportera une m&amp;eacute;thode optimis&amp;eacute;e&amp;hellip;&lt;/p&gt;</description><pubDate>Tue, 31 Jul 2012 09:50:24 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/tester-l-existence-d-un-fichier-avec-les-api-win32-pour-winrt</guid></item><item><title>Les API Win32 supportés par Metro</title><link>http://c2idotnet.com:80/articles/les-api-win32-supportes-par-metro</link><description>&lt;p&gt;Suite &amp;agrave; mon pr&amp;eacute;c&amp;eacute;dent article, certaines personnes se demandaient qu'elles &amp;eacute;taient ces fameuses API Win32 support&amp;eacute;es par Metro.&lt;/p&gt;
&lt;p&gt;La liste compl&amp;egrave;te est disponible ici : &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205757.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/br205757.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Elles sont class&amp;eacute;es en 10 cat&amp;eacute;gories :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205753.aspx"&gt;Data&lt;/a&gt; : File System, Jet (et oui ;-)) et XML,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205754.aspx"&gt;Devices&lt;/a&gt; : Device access, Game controllers, Windows portable devices,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205755.aspx"&gt;Diagnostics&lt;/a&gt; : Debugging &amp;amp; error handling, Last Error, Windows Error Reporting, Windows Event,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205756.aspx"&gt;Graphics&lt;/a&gt; : Direct2D, Direct3D, DirectWrite, DirectMath, Windows Imaging Component,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh452756.aspx"&gt;Multimedia&lt;/a&gt; : Camera, Core Audio, Media Foundation, XAudio2&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205759.aspx"&gt;Networking&lt;/a&gt; : Dynamic Host Configuration Protocol, Mobile Broadband, Windows Web Services, XML Http Request,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205760.aspx"&gt;Printing &amp;amp; documents&lt;/a&gt; : Printing, XPS documents,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/br205762.aspx"&gt;System&lt;/a&gt; : COM, Compression, DLLs, Info, Integers, Large Integer, Loader, Memory, RDP, Processes, Threads and synchronization, Time,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh452772.aspx"&gt;User interface&lt;/a&gt; : Accessibility, Globalization, Property system, Spell check, Strings, Text services framework, Windows animation,&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh464945.aspx"&gt;Alternatives to Windows APIs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Comme vous pouvez le voir, il y a quand m&amp;ecirc;me pas mal d'APIs qui sont disponilbes nativement dans le framework. Donc &amp;agrave; n'utiliser que si vous n'y arrivez pas avec du simple code C#/VB .NET (non, je ne parlerais pas de javascript ici ;-))).&lt;/p&gt;</description><pubDate>Tue, 31 Jul 2012 09:49:11 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/les-api-win32-supportes-par-metro</guid></item><item><title>De l'évolution du test de l'existence d'un fichier en .NET</title><link>http://c2idotnet.com:80/articles/de-l-evolution-du-test-de-l-existence-d-un-fichier-en-.net</link><description>&lt;p&gt;.NET Framework 1.0, 2002 :&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/actualites/FileExist-2002.jpg" width="800" height="229" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;WINRT&lt;/h1&gt;
&lt;p&gt;Premi&amp;egrave;re solution (&lt;a href="http://blogs.msdn.com/b/eternalcoding/archive/2012/07/04/tips-and-tricks-for-c-metro-developers-the-fileexistsasync-method.aspx"&gt;blog de David Catuhe&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/actualites/FileExist-2012.jpg" width="800" height="457" /&gt;&lt;/p&gt;
&lt;p&gt;2&amp;egrave;me solution (brutale, "&amp;agrave; la Mitsu" ;-))&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/actualites/FileExist-2012-1.jpg" width="800" height="457" /&gt;&lt;/p&gt;
&lt;p&gt;10 ans de progr&amp;egrave;s...&lt;/p&gt;</description><pubDate>Mon, 30 Jul 2012 06:52:14 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/de-l-evolution-du-test-de-l-existence-d-un-fichier-en-.net</guid></item><item><title>De l'utilisation de Skydrive dans ses applications</title><link>http://c2idotnet.com:80/articles/de-l-utilisation-de-skydrive-dans-ses-applications</link><description>&lt;p&gt;&lt;img width="300" height="300" style="padding: 10px; float: right;" alt="" src="/Media/Default/BlogPost/articles/de-l-utilisation-de-skydrive-dans-ses-applications/Skydrive.jpg" /&gt;Si je m'attaque &amp;agrave; ce sujet, c'est que je viens de lire sur Smartphone Fr le billet suivant : Skydrive sur Windows Phone : &lt;a href="http://www.smartphonefrance.info/actu.asp?ID=7586"&gt;Une politique surprenante !&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Suite &amp;agrave; &lt;a href="http://forums.create.msdn.com/forums/t/101154.aspx"&gt;un post sur le forum MSDN de Mark Chamberlain de Microsoft&lt;/a&gt;, il semblerait que l'utilisation de Skydrive pour sauvegarder des donn&amp;eacute;es dans son application Windows Phone n'est pas autoris&amp;eacute;e et qu'en cons&amp;eacute;quence, votre application risquait d'&amp;ecirc;tre rejet&amp;eacute;e.&lt;/p&gt;
&lt;p&gt;Ce post concerne Windows Phone mais touche &amp;eacute;galement Windows 8 (ou alors, je comprends plus rien !).&lt;/p&gt;
&lt;p&gt;Donc le sc&amp;eacute;nario suivant est impossible&amp;nbsp;: vous avez une application WinRT et m&amp;ecirc;me si vous pr&amp;eacute;venez votre utilisateur que vous voulez sauvegarder des donn&amp;eacute;es dans son Skydrive (de toutes fa&amp;ccedil;ons, vous &amp;ecirc;tes oblig&amp;eacute; de l'avertir, ce qui est normal), vous n'en avez pas le droit.&lt;/p&gt;
&lt;p&gt;La seule solution que vous avez pour remonter des informations "in ze cloud" n'est donc que le roaming storage limit&amp;eacute; &amp;agrave; 100Ko.&lt;/p&gt;
&lt;p&gt;Beaucoup trouve cela bizarre, commencent &amp;agrave; crier au scandale, etc.&amp;nbsp;&amp;nbsp;M&amp;ecirc;me si cela m'emb&amp;ecirc;te (pour&amp;nbsp;les applications que je d&amp;eacute;veloppe)&amp;nbsp;d'un autre c&amp;ocirc;t&amp;eacute;,&amp;nbsp;cela se comprend. Bien que vous pr&amp;eacute;venez votre utilisateur de l'utilisateur de son Skydrive, il n'a pas la maitrise des donn&amp;eacute;es qui y seront stock&amp;eacute;es. Ce n'est pas vraiment lui le "moteur", l'intiateur, le controleur&amp;nbsp;de ces donn&amp;eacute;es et il se peut qu'&amp;agrave; terme, son Skydrive soit plein si une application fait n'importe quoi (et en la d&amp;eacute;sinstallant, il ne purgera pas son Skydrive).&lt;/p&gt;
&lt;p&gt;En revanche, je pense que si votre application permet d'enregistrer des documents (tout comme Office), cela devrait &amp;ecirc;tre permis.&lt;/p&gt;
&lt;p&gt;Et vous, vous en pensez quoi ?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Wed, 25 Jul 2012 16:13:21 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/de-l-utilisation-de-skydrive-dans-ses-applications</guid></item><item><title>Office 2013 : point de vue d'un développeur</title><link>http://c2idotnet.com:80/articles/office-2013-point-de-vue-d-un-developpeur</link><description>&lt;p&gt;&lt;img style="padding: 10px; float: right;" alt="" src="/Media/Default/BlogPost/articles/Office2013Preview.png" width="127" height="40" /&gt;Hier, Microsoft a r&amp;eacute;v&amp;eacute;l&amp;eacute; la nouvelle version d'un de ses produits phare (avec Windows), Office 2013. Il s'agit encore d'une beta, ou plus exactement d'une preview (faudra qu'on m'explique un jour la diff&amp;eacute;rence ;-)).&lt;/p&gt;
&lt;p&gt;Donc depuis hier, vous pouvez t&amp;eacute;l&amp;eacute;charger Office 2013 avec Work, Excel, Powerpoint, etc. sur le site suivant : &lt;a href="http://www.microsoft.com/office/preview/en"&gt;http://www.microsoft.com/office/preview/en&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(inutile de passer du temps sur la video d'accueil, ce n'est que du marketing qui ne montre rien).&lt;/p&gt;
&lt;p&gt;Parmi les grandes nouveaut&amp;eacute;s, on notera l'int&amp;eacute;gration de Skydrive dans Office : vous ne sauvegardez plus sur votre disque dur mais dans Skydrive ce qui vous permet d'avoir acc&amp;egrave;s &amp;agrave; vos documents de n'importe ou (enfin les designer avec des powerpoint de plusieurs mega, je leur souhaite bien du courage).&lt;/p&gt;
&lt;p&gt;Je ne parlerai pas des nouveaut&amp;eacute;s d'Office, car franchement, je n'y connais rien en bureautique et ce n'est pas ma passion. Je noterais juste au passage l'int&amp;eacute;gration d'un menu "&amp;agrave; la maya" (logiciel d'image de synth&amp;egrave;se des ann&amp;eacute;es 90 rachet&amp;eacute; par Autodesk depuis) dans OneNote (pour WinRT) :&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/articles/MayaOneNoteMenu.jpg" width="650" height="268" /&gt;&lt;/p&gt;
&lt;p&gt;(Ca &amp;agrave; pas l'air &amp;eacute;vident comme ca, mais je vous assure &amp;agrave; l'usage que c'est la m&amp;ecirc;me inspiration ;-)).&lt;/p&gt;
&lt;p&gt;Mais le plus important pour nous d&amp;eacute;veloppeur, ce n'est pas tout cela mais le nouveau mod&amp;egrave;le de d&amp;eacute;veloppement propos&amp;eacute; (impos&amp;eacute; ?)&amp;nbsp;par Microsoft.&lt;/p&gt;
&lt;h2&gt;Macros &amp;amp; mod&amp;egrave;le COM toujours pr&amp;eacute;sents&lt;/h2&gt;
&lt;p&gt;Que les afficionados de VBA se rassurent : les macros Visual Basic sont toujours pr&amp;eacute;sentes avec l'&amp;eacute;diteur de macro qui n'a pas boug&amp;eacute; d'un iota. On retrouve la m&amp;ecirc;me interface, les m&amp;ecirc;mes boutons (pas de ribbon), les m&amp;ecirc;me menu (en camel case, pas en upper case), etc.&lt;/p&gt;
&lt;p&gt;Bref, ils n'y ont pas touch&amp;eacute;s. Certains diront : on ne change pas une &amp;eacute;quipe qui gagne. OK, why not.&lt;/p&gt;
&lt;p&gt;Comme on a donc toujours ces objets COM expos&amp;eacute;s, je suppose que l'on a aussi les wrappers pour .NET qui vont bien et que l'on a des projets mod&amp;egrave;les dans Visual Studio qui permettent de cr&amp;eacute;er des compl&amp;egrave;tements d'Office en .NET avec C#ou Visual Basic .NET, avec un vrai langage moderne quoi.&lt;/p&gt;
&lt;p&gt;NB : j'ai install&amp;eacute; Office 2013 sur une tablette Samsung Slate avec Windows 8 Preview qui n'avait pas Visual Studio 2012 Preview d'install&amp;eacute;, je n'ai donc pu v&amp;eacute;rifier ce point.&lt;/p&gt;
&lt;p&gt;Et, comme de sous-entendu, j'en viens au nouveau mod&amp;egrave;le de programmation propos&amp;eacute; (impos&amp;eacute;) par Microsoft.&lt;/p&gt;
&lt;h2&gt;Office Apps, Apps for Office, as you want.&lt;/h2&gt;
&lt;p&gt;L'id&amp;eacute;e de Microsoft est de permettre &amp;agrave; des &amp;eacute;diteurs de d&amp;eacute;velopper des applications pour Office distribuables via le Windows Store (avec une "sp&amp;eacute;cialisation", l'Office Store)&amp;nbsp;et&amp;nbsp;installables sur des Windows 8 WinRT (aka pour ARM). Il fallait donc pour cela que l'application puisse suivre le mod&amp;egrave;le de s&amp;eacute;curit&amp;eacute;, de sandbox de WinRT.&lt;/p&gt;
&lt;p&gt;La solution, et l'unique solution qui a &amp;eacute;t&amp;eacute; trouv&amp;eacute;e, est de permettre le d&amp;eacute;veloppement d'applications en&amp;nbsp;HTML5/javascript. Donc pour r&amp;eacute;sumer,&amp;nbsp;sur un langage invent&amp;eacute; en 1995 et une techno encore en draft. L'avantage, c'est que vous allez pouvoir int&amp;eacute;grer des projets/framework Open Source comme jQuery dans vos applis Office. L'inconv&amp;eacute;nient c'est que, comme html5 est toujours en draft, Microsoft ajoute ses propres sp&amp;eacute;cificit&amp;eacute;s qui font que ce n'est pas aussi universel que cela en &amp;agrave; l'air. De plus, quand on voit la guerre les diff&amp;eacute;rences d'interpr&amp;eacute;tations entre IE, Chrome, Firefox &amp;amp; co sur du Html5, ce n'est pas pr&amp;ecirc;t de se stabiliser tout cela. Enfin bon, c'est un couple, Html5/javascrip&amp;nbsp;qui &amp;agrave; l'avantage d'&amp;ecirc;tre connu de tous.&lt;/p&gt;
&lt;p&gt;Vous pouvez d&amp;eacute;velopper 3 types d'applications :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Task pane app : vous d&amp;eacute;veloppez le contenu d'une fen&amp;ecirc;tre qui apparait ancr&amp;eacute;e sur la droite de l'application Office (peut apparaitre dans les diff&amp;eacute;rentes applis Office). Par exemple un panneau qui permet de faire une recherche sur Wipikedia et d'afficher l'article dans ce panneau (vous faites un copier-coller dans votre devoir de vacances d'Histoire-g&amp;eacute;o apr&amp;egrave;s ;-))&lt;/li&gt;
&lt;li&gt;Content app : acc&amp;egrave;s s&amp;eacute;pcifique &amp;agrave; un type de document Office (Workbook &amp;amp; co). Le plus proche des applis COM, permettent de manipuler l'arborescence objet de Word/Excel avec une nouvelle repr&amp;eacute;sentation de celle ci.&lt;/li&gt;
&lt;li&gt;Mail app : type sp&amp;eacute;ciale d'appli permettant d'envoyer des emails (sp&amp;eacute;cifique Outlook 2013).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Toute application, pardon App, pour&amp;nbsp;Office est compos&amp;eacute;e d'un manifeste (document xml) et de son "code" en javascript. Oui, c'est du javascript, et pas autre chose (j'insiste car quand vous allez sur &lt;a href="http://code.msdn.microsoft.com/officeapps/site/search?f%5B0%5D.Type=Technology&amp;amp;f%5B0%5D.Value=apps%20for%20Office"&gt;la page des exemples&lt;/a&gt;, vous avez des exemples dits en C#/VB .NET qui ne contiennent pas une ligne de .NET&amp;nbsp;&amp;nbsp;;-)).&lt;/p&gt;
&lt;p&gt;Comme l'appli ne repose que sur ces technologies, la bonne nouvelle c'est que vous pouvez les d&amp;eacute;velopper avec un "vieux" Visual Studio 2012.&lt;/p&gt;
&lt;h2&gt;Un pari sur l'avenir&lt;/h2&gt;
&lt;p&gt;Je pense qu'il est clair que Microsoft essaye d'inventer un nouveau march&amp;eacute;. Comme Office sera "offert" avec WinRT, la solution qu'ils ont trouv&amp;eacute;s pour se r&amp;eacute;munerer&amp;nbsp;est de permettre la diffusion d'appli dans le Windows Store (et donc de prendre 30% de com au passage). C'est ing&amp;eacute;nieux.&lt;/p&gt;
&lt;p&gt;La bonne nouvelle c'est qu'Office deviendra de moins en moins cher si cet echo-syst&amp;egrave;me se d&amp;eacute;veloppe.&lt;/p&gt;
&lt;p&gt;La moins bonne nouvelle, c'est que le d&amp;eacute;veloppement .NET semble abandonn&amp;eacute;. Maintenant, je n'y mettrais pas ma main au feu et peut-&amp;ecirc;tre qu'une bonne nouvelle sera annonc&amp;eacute;e prochainement (&amp;agrave; moins que je n'ai pas tout compris...).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/office/apps/jj220060(v=office.15)"&gt;Le point d'entr&amp;eacute;e pour le d&amp;eacute;veloppement d'Office Apps (ou Apps for Office).&lt;/a&gt;&lt;/p&gt;</description><pubDate>Tue, 17 Jul 2012 09:12:53 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/office-2013-point-de-vue-d-un-developpeur</guid></item><item><title>Comment charger et afficher beaucoup d'images (WinForms)</title><link>http://c2idotnet.com:80/articles/comment-charger-et-afficher-beaucoup-d-rsquo-images-winforms</link><description>&lt;p&gt;L&amp;rsquo;id&amp;eacute;e de cet article me vient d&amp;rsquo;une question pos&amp;eacute;e sur le forum MSDN de C#. La question &amp;eacute;tait la suivante :&lt;/p&gt;
&lt;p&gt;&lt;em&gt;J&amp;rsquo;ai un r&amp;eacute;pertoire avec beaucoup d&amp;rsquo;images et je souhaite les afficher dans une Windows Form. Le probl&amp;egrave;me est que j&amp;rsquo;ai un OutOfMemoryException qui se d&amp;eacute;clenche. Comment faire ?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Bien entendu, si l&amp;rsquo;on a beaucoup d&amp;rsquo;images en haute r&amp;eacute;solution, vous aurez beau avoir un PC de la mort qui tue, la m&amp;eacute;moire n&amp;rsquo;est pas extensible &amp;agrave; l&amp;rsquo;infini. Donc charger "simplement&amp;rdquo; les images dans des PictureBox ou dans une DataGrid fera que votre PC chauffera.&lt;/p&gt;
&lt;h2&gt;Le principe&lt;/h2&gt;
&lt;p&gt;Nous allons donc cr&amp;eacute;er un projet Windows Form (je crois que ca fait 6 ans que je n&amp;rsquo;en avais pas fait &lt;img style="border-style: none;" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d'&amp;oelig;il" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Comment-charger-et-afficher-beaucoup-dim_8CD0/wlEmoticon-winkingsmile_2.png" /&gt;). Il comportera simplement un bouton pour lancer l&amp;rsquo;analyse et un contr&amp;ocirc;le Panel dans lequel nous allons ajouter dynamiquement des contr&amp;ocirc;les PictureBox.&lt;/p&gt;
&lt;p&gt;Quand on clique sur le bouton d&amp;rsquo;analyse, une premi&amp;egrave;re m&amp;eacute;thode fera le m&amp;eacute;nage dans notre panel (supprimera les picturebox existants) :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;private void ClearImageControls()
{
    // on supprime les picturebox existants
    if (pnImages.Controls.Count &amp;gt; 0)
    {
        for (var index = pnImages.Controls.Count - 1; index &amp;gt;= 0; index--)
        {
            var ctrlImage = pnImages.Controls[index] as PictureBox;
            if (ctrlImage != null)
            {
                pnImages.Controls.RemoveAt(index);
                ctrlImage.Image = null;
                ctrlImage.Dispose();
            }
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Et donc nous appellerons cette m&amp;eacute;thode pour vider notre contr&amp;ocirc;le Panel.&lt;/p&gt;
&lt;p&gt;Maintenant, le c&amp;oelig;ur de notre code va &amp;ecirc;tre pour chaque fichier image contenu dans notre r&amp;eacute;pertoire :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Charger l&amp;rsquo;image,&lt;/li&gt;
&lt;li&gt;Cr&amp;eacute;er une vignette de limage,&lt;/li&gt;
&lt;li&gt;D&amp;eacute;charger l&amp;rsquo;image,&lt;/li&gt;
&lt;li&gt;Ajouter un PictureBox contenant la vignette &amp;agrave; notre Panel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&amp;rsquo;est donc, dans un premier temps, une approche synchrone, qui prend du temps et qui g&amp;egrave;le l&amp;rsquo;interface (pas cool) :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;private void btnSync_Click(object sender, EventArgs e)
{
    // La madame elle fait le m&amp;eacute;nache
    ClearImageControls();
    // on mesure le  temps d'ex&amp;eacute;cution
    var sw = Stopwatch.StartNew();
    
    var currentColumn = 0;
    var currentRow = 0;
    // pour toutes les images du r&amp;eacute;pertoire
    foreach (var fileName in Directory.GetFiles(FolderName, "*.jpg"))
    {
        // On charge l'image
        Image img = new Bitmap(fileName);
        // On en fait une vignette
        var newImage = img.GetThumbnailImage(PictureWidth, PictureWidth, null, IntPtr.Zero);
        // on d&amp;eacute;charge l'image
        img.Dispose();

        // on cr&amp;eacute;e le PictureBox
        var newPic = new PictureBox
                         {
                             Width = PictureWidth,
                             Height = PictureWidth,
                             Location = new Point
                                            {
                                                X = currentColumn*(PictureWidth + PictureMargin),
                                                Y = currentRow*(PictureWidth + PictureMargin)
                                            },
                             Image = newImage,
                         };

        // On ajoute le PictureBox dans le Panel
        pnImages.Controls.Add(newPic);

        // On g&amp;egrave;re les colonnes, lignes
        currentColumn++;
        if (currentColumn &amp;gt;= ColumnsNumber)
        {
            currentColumn = 0;
            currentRow++;
        }
    }

    // Affichage du temps d'ex&amp;eacute;cution
    lbl.Text = string.Format("{0} ms", sw.ElapsedMilliseconds);
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;R&amp;eacute;sultat sur un r&amp;eacute;pertoire contenant 350 images tr&amp;egrave;s haute r&amp;eacute;solution (1 Go d&amp;rsquo;images jpeg) :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Comment-charger-et-afficher-beaucoup-dim_8CD0/LoadImages0.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="LoadImages0" border="0" alt="LoadImages0" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Comment-charger-et-afficher-beaucoup-dim_8CD0/LoadImages0_thumb.jpg" width="755" height="419" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Une minute, c&amp;rsquo;est pas mal, mais j&amp;rsquo;ai un &amp;ldquo;beau PC&amp;rdquo; &lt;img style="border-style: none;" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d'&amp;oelig;il" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Comment-charger-et-afficher-beaucoup-dim_8CD0/wlEmoticon-winkingsmile_2.png" /&gt;.&lt;/p&gt;
&lt;h2&gt;L&amp;rsquo;approche asynchrone&lt;/h2&gt;
&lt;p&gt;Bien entendu, le mieux est d&amp;rsquo;avoir une approche asynchrone, ce que nous permet facilement le Framework 4.0. Nous allons donc lancer une t&amp;acirc;che qui va it&amp;eacute;rer sur l&amp;rsquo;ensemble des fichiers et retourner la liste des vignettes :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;// D&amp;eacute;marrage en asynchrone
            Task&amp;lt;IEnumerable&amp;lt;Image&amp;gt;&amp;gt;.Factory.StartNew(
                () =&amp;gt;
{
    // chargement des vignettes dans un ConcurrentBag
    var images = new ConcurrentBag&amp;lt;Image&amp;gt;();
    Parallel.ForEach(Directory.GetFiles(FolderName, "*.jpg"),
                     fileName =&amp;gt;
                         {
                             // On charge l'image
                             Image img = new Bitmap(fileName);
                             // On en fait une vignette
                             var newImage = img.GetThumbnailImage(
                                 PictureWidth,
                                 PictureWidth,
                                 null,
                                 IntPtr.Zero);
                             images.Add(newImage);
                             img.Dispose();
                         });
    return images;
}).ContinueWith(...);
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Donc maintenant, dans ContinueWith, on a notre collection d&amp;rsquo;images que l&amp;rsquo;on peut ajouter dans le Panel :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;.ContinueWith(
task =&amp;gt;
    {
        // on n'a pas de gestion d'erreur ici, mais ce serait une bonne id&amp;eacute;e quand m&amp;ecirc;me
        var currentColumn = 0;
        var currentRow = 0;
        foreach (var image in task.Result)
        {
            var newPic = new PictureBox
            {
                Width = PictureWidth,
                Height = PictureWidth,
                Location = new Point
                {
                    X = currentColumn * (PictureWidth + PictureMargin),
                    Y = currentRow * (PictureWidth + PictureMargin)
                },
                Image = image,
            };
            pnImages.Controls.Add(newPic);

            // On g&amp;egrave;re les colonnes, lignes
            currentColumn++;
            if (currentColumn &amp;gt;= ColumnsNumber)
            {
                currentColumn = 0;
                currentRow++;
            }
        }
        lbl.Text = string.Format("{0} ms", sw.ElapsedMilliseconds);
    },
TaskScheduler.FromCurrentSynchronizationContext());
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Notez l&amp;rsquo;utiilisation de TaskScheduler.FromCurrentSynchronizationContext() pour s&amp;rsquo;assurer que le r&amp;eacute;sultat est analyser dans le thread de l&amp;rsquo;UI.&lt;/p&gt;
&lt;p&gt;Moralit&amp;eacute; :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Comment-charger-et-afficher-beaucoup-dim_8CD0/LoadImages1.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="LoadImages1" border="0" alt="LoadImages1" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Comment-charger-et-afficher-beaucoup-dim_8CD0/LoadImages1_thumb.jpg" width="755" height="419" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le r&amp;eacute;sultat est le m&amp;ecirc;me (bonne nouvelle !) et surtout, le temps d&amp;rsquo;ex&amp;eacute;cution a &amp;eacute;t&amp;eacute; s&amp;eacute;rieusement diminu&amp;eacute; (14 secondes au lieu d&amp;rsquo;une minute) et l&amp;rsquo;interface de l&amp;rsquo;utilisateur n&amp;rsquo;a pas &amp;eacute;t&amp;eacute; fig&amp;eacute;e. On pourrait rajouter l&amp;rsquo;affichage d&amp;rsquo;une image anim&amp;eacute;e pour signifier que l&amp;rsquo;on travaille, ajouter des informations sur le d&amp;eacute;roulement de l&amp;rsquo;analyser, etc. Mais je vais pas vous m&amp;acirc;cher tout le travail quand m&amp;ecirc;me &lt;img style="border-style: none;" class="wlEmoticon wlEmoticon-winkingsmile" alt="Clignement d'&amp;oelig;il" src="http://www.c2idotnet.com/Media/Default/Windows-Live-Writer/Comment-charger-et-afficher-beaucoup-dim_8CD0/wlEmoticon-winkingsmile_2.png" /&gt;.&lt;/p&gt;
&lt;p&gt;Le code complet en mode asynchrone est donc le suivant :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;private void async_btnSync_Click(object sender, EventArgs e)
{
    // La madame elle fait le m&amp;eacute;nache
    ClearImageControls();
    // on mesure le  temps d'ex&amp;eacute;cution
    var sw = Stopwatch.StartNew();

    // D&amp;eacute;marrage en asynchrone
    Task&amp;lt;IEnumerable&amp;lt;Image&amp;gt;&amp;gt;.Factory.StartNew(
        () =&amp;gt;
            {
                // chargement des vignettes dans un ConcurrentBag
                var images = new ConcurrentBag&amp;lt;Image&amp;gt;();
                Parallel.ForEach(Directory.GetFiles(FolderName, "*.jpg"),
                                 fileName =&amp;gt;
                                     {
                                         // On charge l'image
                                         Image img = new Bitmap(fileName);
                                         // On en fait une vignette
                                         var newImage = img.GetThumbnailImage(
                                             PictureWidth,
                                             PictureWidth,
                                             null,
                                             IntPtr.Zero);
                                         images.Add(newImage);
                                         img.Dispose();
                                     });
                return images;
            }).ContinueWith(
                task =&amp;gt;
                    {
                        // on n'a pas de gestion d'erreur ici, mais ce serait une bonne id&amp;eacute;e quand m&amp;ecirc;me
                        var currentColumn = 0;
                        var currentRow = 0;
                        foreach (var image in task.Result)
                        {
                            var newPic = new PictureBox
                            {
                                Width = PictureWidth,
                                Height = PictureWidth,
                                Location = new Point
                                {
                                    X = currentColumn * (PictureWidth + PictureMargin),
                                    Y = currentRow * (PictureWidth + PictureMargin)
                                },
                                Image = image,
                            };
                            pnImages.Controls.Add(newPic);

                            // On g&amp;egrave;re les colonnes, lignes
                            currentColumn++;
                            if (currentColumn &amp;gt;= ColumnsNumber)
                            {
                                currentColumn = 0;
                                currentRow++;
                            }
                        }
                        lbl.Text = string.Format("{0} ms", sw.ElapsedMilliseconds);
                    },
                TaskScheduler.FromCurrentSynchronizationContext());
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Comme quoi, l&amp;rsquo;asynchrone peut servir m&amp;ecirc;me pour les applications &amp;ldquo;old fashion&amp;rdquo;, aka Windows Form.&lt;/p&gt;</description><pubDate>Fri, 06 Jul 2012 08:25:37 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/comment-charger-et-afficher-beaucoup-d-rsquo-images-winforms</guid></item><item><title>Les raccourcis clavier de Windows 8</title><link>http://c2idotnet.com:80/articles/les-raccourcis-clavier-de-windows-8</link><description>&lt;p&gt;Plut&amp;ocirc;t qu'un long discours, voici une superbe capture d'&amp;eacute;cran de mon clavier avec les raccourcis Windows + Touche de Windows 8 :&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="/Media/Default/BlogPost/articles/Windows8Keyboard-s.png" width="900" height="461" /&gt;&lt;/p&gt;
&lt;p&gt;A noter &amp;eacute;galement :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1 to 9&lt;/strong&gt; - Show/Launch Application from Taskbar &lt;br /&gt;&lt;strong&gt;Page Up/Down&lt;/strong&gt; - Moves tiles to the left/right &lt;br /&gt;&lt;strong&gt;Tab&lt;/strong&gt; - Switch between applications &lt;br /&gt;&lt;strong&gt;, (comma)&lt;/strong&gt; - Aero Peek (desktop) &lt;br /&gt;&lt;strong&gt;. (full stop)&lt;/strong&gt; - Snap Metro style app to right side of the screen &lt;br /&gt;&lt;strong&gt;Shift . (full stop)&lt;/strong&gt; - Snap Metro style app to the left side of the screen &lt;br /&gt;&lt;strong&gt;Space&lt;/strong&gt; - Switch input language and keyboard layout &lt;br /&gt;&lt;strong&gt;Enter&lt;/strong&gt; - Launch Narrator &lt;br /&gt;&lt;strong&gt;Arrow keys&lt;/strong&gt; - Aero Snap (desktop)&lt;/p&gt;
&lt;p&gt;&lt;a href="/Media/Default/BlogPost/articles/Windows8Keyboard.jpg"&gt;L'image en haute r&amp;eacute;solution&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ce sh&amp;eacute;ma est bas&amp;eacute; sur &lt;a href="http://blogs.msdn.com/b/richin/archive/2012/07/03/windows-8-keyboard-shortcuts.aspx"&gt;le billet suivant&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Utile ?&lt;/p&gt;</description><pubDate>Tue, 03 Jul 2012 15:53:37 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/les-raccourcis-clavier-de-windows-8</guid></item><item><title>Comment redimensionner une image avec WinRT : plusieurs solutions</title><link>http://c2idotnet.com:80/articles/comment-redimensionner-une-image-avec-winrt-plusieurs-solutions</link><description>&lt;p&gt;J'ai particip&amp;eacute; hier &amp;agrave; une session du Tour de France Windows 8 &amp;agrave; Bordeaux. Session tr&amp;egrave;s sympathique avec de charmants co-d&amp;eacute;veloppeurs.&lt;/p&gt;
&lt;p&gt;J'en ai profit&amp;eacute; pour m'avancer sur mon projet d'application WinRT et de me pencher plus avant sur la probl&amp;eacute;matique suivante :&lt;/p&gt;
&lt;p&gt;J'ai des nombreuses images dans mon application qui sont de taille "importante" (sup&amp;eacute;rieure &amp;agrave;&amp;nbsp;1024*768). Or il se trouve que ces images peuvent &amp;ecirc;tre utilis&amp;eacute;es pour la vignette de mon application. J'ai donc soit le choix de cr&amp;eacute;er "&amp;agrave; la main" une version light de mes images, soit ajouter la fonctionnalit&amp;eacute; &amp;agrave; mon application de redimensionnement d'images (pour info, le poids&amp;nbsp;des images affich&amp;eacute;es dans les vignettes est limit&amp;eacute;e, 150Ko je crois de m&amp;eacute;moire).&lt;/p&gt;
&lt;p&gt;La solution que j'ai trouv&amp;eacute;e &amp;eacute;tait la suivante :&lt;/p&gt;
&lt;h2&gt;Une solution "pas simple"&lt;/h2&gt;
&lt;p&gt;La premi&amp;egrave;re &amp;eacute;tape consiste &amp;agrave; r&amp;eacute;cup&amp;eacute;rer la premi&amp;egrave;re frame de l'image &amp;agrave; partir du fichier :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;// imageFilename 
//      C'est le nom du fichier. 
//      Ici, c'est un fichier image que l'on a plac&amp;eacute; dans notre projet en tant que Contenu
//      (r&amp;eacute;pertoire Assets dans le projet template de MS) 
//      Il se trouve donc dans le InstalledLocation
//      r&amp;eacute;cup&amp;eacute;ration du fichier, StorageFile
// fileName
//      nom du fichier que l'on veut sauvegarder
// width, height
//      largeur et hauteur de l'image finale d&amp;eacute;sir&amp;eacute;e

var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFilename);
// r&amp;eacute;cup&amp;eacute;ration du flux du fichier
var baseStream = RandomAccessStreamReference.CreateFromFile(file);
// d&amp;eacute;codeur de l'image &amp;agrave; partir du flux ouvert en lecture
var fileDecoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(await baseStream.OpenReadAsync());
// r&amp;eacute;cup&amp;eacute;ration de la premi&amp;egrave;re frame de l'image
var bitmapFrame = await fileDecoder.GetFrameAsync(0);&lt;/pre&gt;
&lt;p&gt;Ensuite, on r&amp;eacute;cup&amp;egrave;re les pixels de notre image en sp&amp;eacute;cifiant la taille de l'image finale :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;// on veut une image de la taille width*height
var bitmapTransform = new BitmapTransform { ScaledWidth = width, ScaledHeight = height };
// r&amp;eacute;cup&amp;eacute;ration des pixels
var pixelDatas =
    await bitmapFrame.GetPixelDataAsync(
        bitmapFrame.BitmapPixelFormat,
        bitmapFrame.BitmapAlphaMode,
        bitmapTransform,
        ExifOrientationMode.IgnoreExifOrientation,
        ColorManagementMode.DoNotColorManage);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Enfin, on cr&amp;eacute;e le fichier final et on &amp;eacute;crit les pixels dedans :&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;// le fichier ou l'on souhaite enregistrer l'image redimensionn&amp;eacute;e.
// On la place dans le LocalFolder de l'application
var targetFile =
    await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(
        fileName,
        CreationCollisionOption.ReplaceExisting)
        .AsTask&amp;lt;storagefile&amp;gt;();

// ouverture du flux pour &amp;eacute;crire dans le fichier
using (var fileStream = await targetFile.OpenAsync(FileAccessMode.ReadWrite))
{
    // l'encodeur de notre nouveau fichier image
    var newBitmapEncoder = 
        await Windows.Graphics.Imaging.BitmapEncoder.CreateAsync(
            BitmapEncoder.JpegEncoderId, 
            fileStream);
    // on &amp;eacute;crit les pixels dans notre nouveau fichier en respectant les infos d'origine (dpi, alpha, etc.)
    newBitmapEncoder.SetPixelData(
        bitmapFrame.BitmapPixelFormat, 
        bitmapFrame.BitmapAlphaMode, 
        bitmapTransform.ScaledWidth, 
        bitmapTransform.ScaledHeight, 
        bitmapFrame.DpiX, 
        bitmapFrame.DpiY, 
        pixelDatas.DetachPixelData());

    // on s'assure que l'on vide bien tout
    await newBitmapEncoder.FlushAsync();
    await fileStream.FlushAsync();
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ce n'est pas vraiment simple, mais ca marche.&lt;/p&gt;
&lt;h2&gt;Une solution plus simple&lt;/h2&gt;
&lt;p&gt;Montrant ce code &amp;agrave; notre cher GO, aka Benoit Laut de Bewise, il me dit : "Mais non, esp&amp;egrave;ce d'abruti, y'a beaucoup plus simple :!".&lt;/p&gt;
&lt;p&gt;Bon, OK, il m'a pas dit ca comme ca exactement ;-). Je pr&amp;eacute;cise pour ceux qui comprendrait pas le second degr&amp;eacute;. Il m'a dit tr&amp;egrave;s gentillement qu'il pensait qu'il y avait plus simple, notamment avec les m&amp;eacute;thodes GetThumbnails du framework. Il a donc recherch&amp;eacute; et quelques temps plus tard, il m'a trouv&amp;eacute; le code suivant :&lt;/p&gt;
&lt;pre class="brush:csharp;"&gt;var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFilename);
// on veut une vignette de type image de largeur width et redimensionn&amp;eacute;e
var thumbnail = await file.GetThumbnailAsync(
    Windows.Storage.FileProperties.ThumbnailMode.PicturesView, 
    width, 
    Windows.Storage.FileProperties.ThumbnailOptions.ResizeThumbnail);

// on cr&amp;eacute;e le fichier cible
var storageFile = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
// ATTENTION : Ajoutez System.IO qui comprend ces m&amp;eacute;thodes d'extensions
// le flux ou l'on souhaite &amp;eacute;crire
var writer = await storageFile.OpenStreamForWriteAsync(); 
var outputStream = writer.AsOutputStream();

// sauvegarde dans le flux de la vignette
await RandomAccessStream.CopyAndCloseAsync(thumbnail, outputStream);&lt;/pre&gt;
&lt;p&gt;Il y a quand m&amp;ecirc;me beaucoup moins de ligne de code, et ca &amp;agrave; l'air plus simple.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;MAIS&lt;/h2&gt;
&lt;p&gt;Car souvent avec moi, il y a un MAIS. J'ai donc voulu voir le r&amp;eacute;sultat de ces deux possibilit&amp;eacute;s. Concr&amp;egrave;tement, on obtient bien une vignette avec la taille d&amp;eacute;sir&amp;eacute;e (dans le deuxi&amp;egrave;me cas, on ne peut pas sp&amp;eacute;cifier la largeur ET la hauteur, mais ce n'est pas grave dans notre cas). Les deux images sont bien g&amp;eacute;n&amp;eacute;r&amp;eacute;es :&lt;/p&gt;
&lt;p&gt;&lt;img width="733" height="236" alt="" src="/Media/Default/BlogPost/articles/comment-redimensionner-une-image-avec-winrt-plusieurs-solutions/redimImage.JPG" /&gt;&lt;/p&gt;
&lt;p&gt;J'ai bien mes patates redimensionn&amp;eacute;es et on peut constater que le temps d'ex&amp;eacute;cution est sensiblement le m&amp;ecirc;me.&lt;/p&gt;
&lt;p&gt;Mais concernant le poids des fichiers, ce n'est pas du tout la m&amp;ecirc;me histoire.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Le fichier d'origine fait 250Ko.&lt;/li&gt;
&lt;li&gt;Le ficher avec la m&amp;eacute;thode complexe fait 36Ko&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Le fichier avec la m&amp;eacute;thode simple fait 250Ko !!!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C'est bizarre (et si vous avez une explication, je suis preneur). Mais toujours est-il que je vas donc utiliser la m&amp;eacute;thode "complexe" dans mon application.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Tout comme dans le framework .NET "normal", pour faire une m&amp;ecirc;me op&amp;eacute;ration, on a de multiples possibilit&amp;eacute;s. Mais l'avantage avec le framework normal, c'est que gr&amp;acirc;ce &amp;agrave; des d&amp;eacute;compilateurs, on peut savoir pourquoi. Peux &amp;ecirc;tre que sur des images beaucoup plus lourde, la solution complexe est beaucoup plus rapide, peux &amp;ecirc;tre qu'avec la version finale, le poid de l'image finale sera optimis&amp;eacute;e.&lt;/p&gt;
&lt;p&gt;Mais comme on n'a pas acc&amp;egrave;s &amp;agrave; des d&amp;eacute;compilateurs pour voir le code qui est r&amp;eacute;ellement ex&amp;eacute;cut&amp;eacute;, on est encore dans le flou, et seul des tests permettent de savoir ce qu'il faut utiliser.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Fri, 11 May 2012 13:48:33 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/comment-redimensionner-une-image-avec-winrt-plusieurs-solutions</guid></item><item><title>Réflechissons un peu ce matin à propos des ORM</title><link>http://c2idotnet.com:80/articles/reflechissons-un-peu-ce-matin-a-propos-des-orm</link><description>&lt;p&gt;&lt;img src="/Media/Default/BlogPost/articles/reflechissons-un-peu-ce-matin-a-propos-des-orm/usine_a_gaz.jpg" alt="Le blog des bits" width="700" height="405" /&gt;&lt;br /&gt;&lt;em&gt;&lt;a href="http://nurdcartoon.blogspot.fr/2008/02/usine-gaz.html"&gt;Le blog des bits&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Fabrice Marguerie (ca faisait une paille que t'avais rien &amp;eacute;cris ;-)) vient de publier&lt;a href="http://weblogs.asp.net/fmarguerie/archive/2012/05/11/object-relational-mapping-tools-reality-check.aspx"&gt;&amp;nbsp;un petit billet&lt;/a&gt;&amp;nbsp;qui fait surtout r&amp;eacute;f&amp;eacute;rence &amp;agrave;&amp;nbsp;&lt;a href="http://martinfowler.com/bliki/OrmHate.html"&gt;un autre billet&lt;/a&gt;&amp;nbsp;de Martin Fowler (vous connaissez bien entendu Martin Fowler).&lt;/p&gt;
&lt;p&gt;Le sujet est &amp;agrave; propos des outils ORM, Object-Relational Mapping tools.&lt;/p&gt;
&lt;p&gt;En gros, ne vous laissez pas aveugler par ces outils, en supputant qu'ils r&amp;eacute;solvent tous vos probl&amp;egrave;mes. Ils peuvent couvrir 80% de votre solution, mais il en restera toujours 20% &amp;agrave; traiter avec attention.&lt;/p&gt;
&lt;p&gt;Et c'est l&amp;agrave; ou j'ajouterais que si vous choisissez de partir avec un outil d'ORM, il faut imp&amp;eacute;rativement que ce dernier vous permette d'inclure du code personnalis&amp;eacute;, que vous ne soyez pas prisonnier de votre ORM. Car la plupart du temps, les 20% de code qu'il vous faut faire &amp;agrave; la main, c'est justement les parties les plus d&amp;eacute;licates, les plus complexes, au niveau de la compr&amp;eacute;hension du fonctionnel. Et j'ai vu souvent des arguments de d&amp;eacute;veloppeur indiquant qu'il faut modifier le fonctionnel pour impl&amp;eacute;menter une fonctionnalit&amp;eacute; car le choix de leur outil faisait que ce n'&amp;eacute;tait pas possible.&lt;/p&gt;
&lt;p&gt;Alors oui je pense &amp;agrave; des outils comme NHibernate ou Entity Framework (quoique) qui font que c'est souvent une usine &amp;agrave; gaz qui sort des cartons, qui fait que le d&amp;eacute;veloppeur passe beaucoup de temps &amp;agrave; essayer de comprendre comment d&amp;eacute;tourner son ORM pour terminer son petit WorkItem.&lt;/p&gt;
&lt;p&gt;Je pense &amp;agrave; un outil comme&amp;nbsp;&lt;a href="http://www.softfluent.com/"&gt;CodeFluent Entities&lt;/a&gt;&amp;nbsp;qui lui au contraire est suffisamment mal&amp;eacute;able, flexible pour int&amp;eacute;grer facilement du code personnalis&amp;eacute; (mais qui d'un autre c&amp;ocirc;t&amp;eacute; vous g&amp;eacute;n&amp;egrave;re 80% de votre plomberie). Il a m&amp;ecirc;me &amp;eacute;t&amp;eacute; con&amp;ccedil;u dans ce sens.&lt;/p&gt;
&lt;p&gt;Donc je le r&amp;eacute;p&amp;egrave;te, faites attention &amp;agrave; l'ORM que vous choisissez. Pensez que quand vous choisissez un ORM, cela vous engage pour toute la dur&amp;eacute;e du produit (et pas seulement le temps de son d&amp;eacute;veloppement), et surtout, soyez certain qu'il y aura des features non couvertes par votre ORM.&lt;/p&gt;</description><pubDate>Fri, 11 May 2012 06:34:46 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/reflechissons-un-peu-ce-matin-a-propos-des-orm</guid></item><item><title>Tuile ou vignette ?</title><link>http://c2idotnet.com:80/articles/tuile-ou-vignette</link><description>&lt;p&gt;Le terme "Tile" est apparu dans le vocabulaire de Microsoft avec Windows Phone 7 et sa nouvelle interface.&lt;/p&gt;
&lt;p&gt;La traduction fran&amp;ccedil;aise (si je ne m'abuse) qui a &amp;eacute;t&amp;eacute; ent&amp;eacute;rin&amp;eacute;e depuis est : tuile. (why not).&lt;/p&gt;
&lt;p&gt;On s'y &amp;eacute;tait habitu&amp;eacute; et tout allait bien.&lt;/p&gt;
&lt;p&gt;Avec Windows 8 Metro, on a encore une fois la pr&amp;eacute;sence de "Tile" dans l'interface du bureau new look. Et ce matin, en consultant la traduction d'un billet du blog des d&amp;eacute;veloppeurs d'applications Windows 8, je vois le titre :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Creating a great tile experience (part 1)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;traduit en :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cr&amp;eacute;ation d'une exp&amp;eacute;rience utilisateur optimale en mati&amp;egrave;re de vignettes (premi&amp;egrave;re partie)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Donc tile pour Windows 8 a &amp;eacute;t&amp;eacute; traduit en vignette. Marrant non ? C'est la subtilit&amp;eacute; de la langue fran&amp;ccedil;aise, suivant le contexte, un m&amp;ecirc;me mot peut changer de signification.&lt;/p&gt;
&lt;p&gt;Une cocotte par exemple, est un pliage en papier pour un enfant, c'est un ustensile de cuisine pour une m&amp;eacute;nag&amp;egrave;re et une xxx pour l'ado boutonneux.&lt;/p&gt;
&lt;p&gt;On a aussi Store qui a &amp;eacute;t&amp;eacute; traduit en Stocker (plus &amp;eacute;trange encore, vu &lt;a href="http://www.c2i.fr/articles/comment-deployer-son-application-winrt-sur-un-autre-ordinateur"&gt;via l'article pr&amp;eacute;c&amp;eacute;dent&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Bon c'est pas grave. Je pense que l'&amp;eacute;quipe de traduction de Windows 8 a un travail &amp;eacute;norme en ce moment car les d&amp;eacute;lais de traduction sont tr&amp;egrave;s courts entre le moment ou le billet est publi&amp;eacute; et sa traduction. J'ai particip&amp;eacute; &amp;agrave; la traduction de la documentation de .NET 1.0 et de VS 2002, et je peux vous dire que c'est pas de la tarte comme exercice.&lt;/p&gt;
&lt;p&gt;Donc encore une fois : merci de nous offrir cette traduction "en temps presque r&amp;eacute;el".&lt;/p&gt;
&lt;p&gt;Vous avez d'autres exemples de traduction "loufoque" ?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</description><pubDate>Mon, 23 Apr 2012 07:29:45 GMT</pubDate><guid isPermaLink="true">http://c2idotnet.com:80/articles/tuile-ou-vignette</guid></item></channel></rss>