<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>c2i.fr - Win32</title><link>http://www.c2i.fr:80/Tags/Win32</link><description>c2i.fr - Win32</description><item><title>Les API Win32 supportés par Metro</title><link>http://www.c2i.fr: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://www.c2i.fr:80/articles/les-api-win32-supportes-par-metro</guid></item><item><title>Tester l'existence d'un fichier avec les API Win32 pour WinRT</title><link>http://www.c2i.fr: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://www.c2i.fr:80/articles/tester-l-existence-d-un-fichier-avec-les-api-win32-pour-winrt</guid></item></channel></rss>