Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse

NodeBB

  1. Home
  2. Programmation
  3. Développement de logiciels
  4. C#
  5. Utiliser DLLImport

Utiliser DLLImport

Scheduled Pinned Locked Moved C#
2 Posts 2 Posters 2.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D
    D
    davydavek
    wrote on last edited by
    #1

    <div>
    <p><em>Ce tutoriel n'est pas destiné au débutants, mais plutôt a ceux qui ont déjà de l’expérience en C# ou VB.NET </em></p>
    </div>
    <div> </div>
    <div>
    <p><strong><span style="font-size:18px;">DLL ... what ?</span></strong></p>
    </div>
    <div> </div>
    <div>Les DLLs (Dynamic-Link Library) sont des fichiers non-exécutables, qui contiennent des fonctions pouvant être utilisée par d'autres applications.</div>
    <div> </div>
    <div>Windows fonctionne justement avec des DLLs (%windir%\system32\ pour ceux qui voudrait les voir).</div>
    <div> </div>
    <div>Les principales sont : </div>
    <div>-user32.dll (User inferface (MessageBox, Bouttons, etc ...))</div>
    <div>-kernel32.dll (Fichiers, Mémoire, Processus/threads etc...)</div>
    <div>-gdi32.dll (Graphiques) </div>
    <div> </div>
    <div>Ces DLL forment ce qu'on appelle l'<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh447209(v=vs.85).aspx" rel="external nofollow">API* Windows</a>, ou l'API* Win32.</div>
    <div> </div>
    <div>*API : Application Programming Interface</div>
    <div>NB: Il y a aussi ntdll.dll, qui contient l'API Native de Windows.</div>
    <div> </div>
    <div>Dans ce tutoriel je vais donc vous apprendre a importer les fonctions FindWindow et FlashWindow, exportées par user32.dll .</div>
    <div> </div>
    <div> </div>
    <div> </div>
    <div>
    <p><strong><span style="font-size:18px;">DLLImport</span></strong></p>
    </div>
    <div> </div>
    <div>Pour importer ces fonctions, on va utiliser DLLImport, il requiert la classe <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.aspx" rel="external nofollow">DLLImportAttribute</a>, dans le namespace <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.aspx" rel="external nofollow">System.Runtime.InteropServices</a> :</div>
    <div> </div>
    <div>
    <pre class="ipsCode prettyprint lang-auto">
    using System.Runtime.InteropServices;</pre>
    </div>
    <div> </div>
    <div>Description des paramètres :</div>
    <div>-string <strong>dllName</strong> : Le chemin vers la DLL, et son nom. (On va utiliser une DLL de windows donc on n'a pas besoin de spécifier le chemin)</div>
    <div> </div>
    <div>-bool <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.bestfitmapping(v=vs.80).aspx" rel="external nofollow"><strong>BestFitMappig</strong></a> (par défaut true) : Permet de convertir les caractères UNICODE en ANSI, si il est true alors la conversion utilise le caractère ANSI le plus proche (best fit).</div>
    <div> </div>
    <div>-CallingConvention <a href="http://msdn.microsoft.com/en-US/library/system.runtime.interopservices.dllimportattribute.callingconvention(v=vs.80).aspx" rel="external nofollow"><strong>CallingConvention</strong></a> (par défaut CallingConvention.StdCall/Winapi) : Un membre de l'enum <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx" rel="external nofollow">CallingConvention</a>, c'est assez low-level, donc je ne vais pas l'expliquer ici, vous pouvez lire la doc si vous en avez envie.</div>
    <div> </div>
    <div>-CharSet <a href="http://msdn.microsoft.com/en-US/library/system.runtime.interopservices.dllimportattribute.charset(v=vs.80).aspx" rel="external nofollow"><strong>CharSet</strong></a> (par défaut CharSet.Ansi) : En fait certaines fonctions ont deux types. Par exemple MessageBoxA, et MessageBoxW. Pour importer MessageBoxA il faut utiliser Charset.Ansi, et pour MessageBoxW, Charset.Unicode. , L'Ansi, sauvegarde chaque caractère dans un byte, ce qui fait qu'il n'y a que 256 caractère disponibles (dictionnaires "basique" : francais/anglais ...), Charset.Unicode utilise deux bytes (DBCS), ce qui permet d’accéder a 65,536 (256<sup>2</sup>) caractères. (arabe/chinois/coréen etc..)</div>
    <div> </div>
    <div>-string <a href="http://msdn.microsoft.com/en-US/library/system.runtime.interopservices.dllimportattribute.entrypoint(v=vs.80).aspx" rel="external nofollow"><strong>EntryPoint</strong></a> : Le nom de la fonction que vous voulez importer.</div>
    <div> </div>
    <div>-bool <a href="http://msdn.microsoft.com/en-US/library/system.runtime.interopservices.dllimportattribute.exactspelling(v=vs.80).aspx" rel="external nofollow"><strong>ExactSpelling</strong></a> (par défaut false en C# mais true en VB) : Si true, vous devez nommer la fonction avec son nom exact (en incluant le A/W, si nécessaire).</div>
    <div> </div>
    <div>-bool <a href="http://msdn.microsoft.com/en-US/library/system.runtime.interopservices.dllimportattribute.preservesig(v=vs.80).aspx" rel="external nofollow"><strong>PreserveSig</strong></a> (par défaut true) : Quand c'est true, la fonction retourne un integer, et quand c'est false, elle retourne une void. Quand une void autre que S_OK (aussi appelé 0, NULL, ERROR_SUCCESS), une exception est lancée. L'exception correspond au code d'erreur. Si la fonction retourne un int autre que 0, vous pouvez gérer l'erreur comme vous le souhaitez.</div>
    <div> </div>
    <div>-bool <a href="http://msdn.microsoft.com/en-US/library/system.runtime.interopservices.dllimportattribute.setlasterror(v=vs.80).aspx" rel="external nofollow"><strong>SetLastError</strong></a> (par défaut false) : Si y'a une erreur durant l'utilisation de la fonction, on peut utiliser Marshal.GetLastWin32Error pour obtenir le code de l'erreur (error code)</div>
    <div> </div>
    <div>-bool <a href="http://msdn.microsoft.com/en-US/library/system.runtime.interopservices.dllimportattribute.throwonunmappablechar(v=vs.80).aspx" rel="external nofollow"><strong>ThrowOnUnmappableChar</strong></a> (par défaut false) : Si c'est a true et qu'une erreur survient durant la conversion des caractères d'UNICODE a ANSI, ça envoie une exception. Sinon ça remplace le caractère par un '?'.</div>
    <div> </div>
    <div>
    <p>Oui y'a beaucoup de paramètres, mais ils sont rarement tous utilisé en même temps.</p>
    </div>
    <div> </div>
    <div><strong><span style="font-size:18px;">Plateform Invoke</span></strong>
    <p> </p>
    </div>
    <div> </div>
    <div>DLLImport fait partie de la plateforme Invoke (PInvoke).</div>
    <div> </div>
    <div>Pour trouver les prototypes des fonctions qu'on veut utiliser, il faut se rendre sur le Microsoft Developer Network (MSDN).</div>
    <div> </div>
    <div>Par exemple pour <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx" rel="external nofollow">FindWindow</a>, le prototype est : (en C)</div>
    <div>
    <pre class="ipsCode prettyprint lang-auto">
    HWND WINAPI FindWindow(
      In_opt  LPCTSTR lpClassName,
      In_opt  LPCTSTR lpWindowName
    );</pre>
    </div>
    <div> </div>
    <div>Mais on ne peut pas utiliser les types des lib C en C# ... Donc on doit les 'traduire'.</div>
    <div>Un superbe site pour ça : <a href="http://www.pinvoke.net/index.aspx" rel="external nofollow">pinvoke.net</a></div>
    <div> </div>
    <div><strong>Attention ! Ce site ne contient pas les prototypes de TOUTE les fonctions, n’hésitez pas a utiliser Google.</strong></div>
    <div> </div>
    <div>Pour FindWindow le prototype serait donc :</div>
    <div> </div>
    <div>
    <pre class="ipsCode prettyprint lang-auto">
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);</pre>
    </div>
    <div> </div>
    <div>
    <p><strong><span style="font-size:18px;">Un peu de pratique ...</span></strong></p>
    </div>
    <div> </div>
    <div>Ouvrez Visual Studio, on va commencer a coder. (ah bah enfin ... 😛  )</div>
    <div><em>Ouvrez aussi une application ayant un titre facile a écrire, j'utiliserait Paint.</em></div>
    <div> </div>
    <div>Comme dit précédemment :
    <pre class="ipsCode prettyprint lang-auto">
    using System.Runtime.InteropServices;
    // Le 'DLLImport' est habituellement placé au début d'une classe, ou encore dans une classe spécifique. 
     
    [DLLImport("user32.dll", SetLastError = true)]
    static extern IntPtr  FindWindow(string lpClassName, string lpWindowName); 
    //On utilisera lpWindowName, lpClassName restera null.
     
    [DllImport("user32.dll", SetLastError = true)]
            static extern bool FlashWindow(IntPtr hwnd, bool bInvert);
    //hwnd est l'handle (quelque chose que Windows utilise pour identifier des objets) de la fenêtre, qu'on récupère grâce a FindWindow.
    </pre>
    </div>
    <div> </div>
    <div>Puis après on fait notre propre code :</div>
    <div> </div>
    <div>
    <pre class="ipsCode prettyprint lang-auto">
    string sWindowName =  "Untitled - Paint";
     IntPtr hWindow = FindWindow(null,sWindowName); // Je préfère utiliser le nom de la fenêtre, donc je place le premier argument a null.
     
        int error = Marshal.GetLastWin32Error(); // Un peu d'error-checking, la liste des ErrorCodes peut être trouvée ici : SystemErrorCodes
                if (error == 0)
                {
                    FlashWindow(hWindow, true);
     
                    error = Marshal.GetLastWin32Error();
                    if (error == 0)
                        Console.WriteLine("{0} flashed !", sWindowName);
                    else 
                      Console.WriteLine("ErrorCode = {0}", error); 
                }      
                else
                   Console.WriteLine("ErrorCode = {0}", error); // Si il y a une erreur, affiche l'erreur.
    </pre>
    </div>
    <div> </div>
    <div> </div>
    <div> </div>
    <div>
    <p><strong><span style="font-size:18px;">End</span></strong></p>
    </div>
    <div> </div>
    <div>Bon bah voila, je pense que j'ai tout dit sur les bases du DLLImport. Pour plus de lecture : <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute_fields(v=vs.110).aspx" rel="external nofollow">DLLImport Attribute</a></div>
    <div> </div>
    <div>Je n'ai montré que deux API (fonctions dans les DLL de windows), il y en a DES CENTAINES, liste disponible sur le MSDN : <a href="http://msdn.microsoft.com/library/windows/desktop/hh920508(vs.85)" rel="external nofollow">Windows API Index</a></div>
    <div> </div>
    <div>Petit projet qui montre quelques trucs possible avec l'api Windows :</div>
    <div>-<a href="http://davydavek.olympe.in/Tutoriels/DLLImport/WindowsControl.exe" rel="external nofollow">WindowsControl.exe</a> (<a href="https://www.virustotal.com/fr/url/4d5d82b9c51dd413829f12744e526e0a091d0ea757f40968f7df94d2126f7922/analysis/1400792009/" rel="external nofollow">scan VirusTotal</a>)</div>
    <div>-<a href="http://davydavek.olympe.in/Tutoriels/DLLImport/WindowsControl.rar" rel="external nofollow">Source</a> (sans l’exécutable, vous devez le compiler vous-même)</div>
    <div> </div>
    <div>Si vous avez des questions, des commentaires etc. , n’hésitez pas a les poster ici.</div>
    <div> </div>
    <div>En espérant que ça vous aie plu,</div>
    <div> </div>
    <div>Davy.</div>

    C# dev
    github.com/DavyWk

    1 Reply Last reply
    1
    • AzadA
      AzadA
      Azad
      wrote on last edited by
      #2

      <p>Très bon tutoriel : complet, pédagogique, documenté et avec des sources concrètes.<br/>
      Mes félicitations, un très bon début.<br/><br/>
      Surtout que ça peut en intéresser beaucoup, vu les bidouilleurs qu'on a. 😉 <br/>
      +1 rep.</p>

      Administrateur du forum.
      Contactez-moi par message privé ou par mail.

      1 Reply Last reply
      0

      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

      With your input, this post could be even better 💗

      Register Login
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Login or register to search.
      Powered by NodeBB Contributors
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups