DLLImport

    Publicités

Users Who Are Viewing This Thread (Total: 0, Members: 0, Guests: 0)

May 23, 2013
508
0
322
'merica
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​

DLL ... what ?

Les DLLs (Dynamic-Link Library) sont des fichiers non-exécutables, qui contiennent des fonctions pouvant être utilisée par d'autres applications.

Windows fonctionne justement avec des DLLs (%windir%\system32 pour ceux qui voudrait les voir).

Les principales sont :
-user32.dll
-kernel32.dll
-gdi32.dll

Dans ce tutoriel je vais donc vous apprendre a importer les fonctions FindWindow et FlashWindow d'user32.dll .



DLLImport

Pour importer ces fonctions, on va utiliser DLLImport, il requiert la classe InteropServices, dans le namespace System.Runtime :

Code:
using System.Runtime.InteropServices;

Description des paramètres :
-string dllName : Le chemin de la DLL, et son nom. (On va utiliser une DLL de windows donc on n'a pas besoin de spécifier le chemin)

-bool BestFitMappig (par défaut true) : En rapport avec les caractères ANSI et UNICODE, il est utilise quand un caractère UNICODE n'a pas de 'traduction' ANSI. Il ne donne pas un caractère exact, mais le plus proche possible ('Best Fit'). (Il est rarement utilise donc c'est pas grave si vous n'avez pas très bien compris.)

-CallingConvention CallingConvention (par défaut CallingConvention.StdCall : Un membre de l'enum Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!, flemme d'expliquer en détail.


-CharSet CharSet (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. (en gros, l'ASCII (CharSet.Ansi), store chaque caractère dans un byte, ce qui fait qu'il y a 255 caractère disponibles, l'Unicode peut utiliser encore 1 et 4 bytes, c'est comme ca qu'on utilise les caractères chinois/arabes etc... )

-string EntryPoint : Le nom de la fonction que vous voulez importer.

-bool ExactSpelling (par défaut false en C# mais true en VB) : Si false, vous devez importer la fonction avec son nom exact ( avec A ou W a la fin, si nécessaire)

-bool PreserveSig (par défaut true) : Quand c'est true, la fonction retourne un Integer, et quand c'est false, retourne une void. (aussi peu utilisé donc, bon ~)

-bool SetLastError (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)

-bool ThrowOnUnmappableChar (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.

Oui y'a beaucoup de paramètres, mais ils sont rarement tous utilisé en même temps.

Plateform Invoke

DLLImport fait partie de la plateforme Invoke (PInvoke).

Pour trouver les prototypes des fonctions qu'on veut utiliser, il faut se rendre sur le Microsoft Developer Network (MSDN).

Par exemple pour Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!, le prototype est : (en C++)
Code:
HWND WINAPI FindWindow(
  _In_opt_  LPCTSTR lpClassName,
  _In_opt_  LPCTSTR lpWindowName
);

Mais on ne peut pas utiliser les types les lib C++ en C# ... Donc on doit les 'traduire'.
Un superbe site pour ça : Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!

Attention ! Ce site ne contient pas les prototypes de TOUTE les fonctions, n’hésitez pas a utiliser Google.

Pour FindWindow le prototype serait donc :

Code:
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

Un peu de pratique ...

Ouvrez Visual Studio, on va commencer a coder. (ah bah enfin ... :hap:)
Ouvrez aussi une application ayant un titre facile a écrire, j'utiliserait Paint.

Comme dit précédemment :
Code:
using System.Runtime.InteropServices;
// Le 'DLLImport' est habituellement place 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.

Puis après on fait notre propre code :

Code:
string sWindowName =  "Untitled - Paint";
 IntPtr hWindow = FindWindow(null,sWindowName); // Je prefere utiliser le nom de la fenetre, donc je place le premier argument a null.

    int error = Marshal.GetLastWin32Error(); // Un peu d'error-checking, la liste des ErrorCodes peut etre trouvee ici : [URL="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx"]System Error Codes[/URL]
            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.



End

Bon bah voila, je pense que j'ai tout dit sur les bases du DLLImport. Pour plus de lecture : Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!

Je n'ai montré que deux API (fonctions dans les DLL de windows), il y en a DES CENTAINES, liste disponible sur le MSDN : Ce lien n'est pas visible, veuillez vous connecter pour l'afficher. Je m'inscris!
(La liste n'inclut pas les fonctions de la dll native de windows, mais c'est une autre histoire ~ )


Si vous avez des questions, des commentaires etc. , n’hésitez pas a les poster ici.

En espérant que ça vous aie plu,

Davy.
 
Last edited:
Apr 26, 2011
1,315
2
944
26
In my home
Discord
brokeos
Merci pour ce tutoriel, il peu servir pour les débutant :)


*Désolé Ben, je voulais pas t’énerver
 
Last edited:
May 23, 2013
508
0
322
'merica
Petit programme que j'ai fait pour montrer quelques trucs réalisables avec l'API windows.

N’hésitez pas a me MP pour le code source.
 

Attachments

  • WindowsControl.exe
    13.5 KB · Views: 13

Ben

Master Chief
V
Ancien staff
Mar 3, 2011
4,069
3
944
Un peut partout.
@Bwisingw,
osef ? Si j'ai mit ce lien c'est pour certains qui tombe sur ce sujet et qui ne savent pas reconnaitre et adapter ce code en Vb.Net. (Rappel : nous somme section cours pour débutant) Surtout que je me rappel très bien de tes débuts d'apprentissage en .Net et ce n'était pas glorieux (comme tous le monde aux début d'apprentissage de quelque chose de nouveaux) donc te la raconte pas...
Tout ça pour dire, que ce n'est pas parce que maintenant tu as acquis un petit niveaux de connaissance dans ce langage que tu peux te prendre pour "vrais" connaisseur comme tu dis.
Surtout que tu ne dis rien à propos du code ou du tuto en lui-même, alors je vois pas l'utilité de ton commentaire.
Pour en revenir aux vrais sujet traité ici, ton programme est dev en .Net 4.5 donc je peux pas tester (pas compatible avec mon XP) mais j'ai décompilé et vue la source c'est nickel ;)