begin process at 2013 06 18 08:38:45
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

VB.NET

 > UTILISATION DE L'API SENDMESSAGE ENTRE DEUX APPLICATIONS VB.NET

UTILISATION DE L'API SENDMESSAGE ENTRE DEUX APPLICATIONS VB.NET


 Information sur la source

Note :
Aucune note
Catégorie :VB.NET Source .NET ( DotNet ) Classé sous :SendMessage, Marshal, WndProc, WriteProcessMemory, VirtualAllocEx Niveau :Initié Date de création :23/05/2012 Date de mise à jour :23/05/2012 11:05:32 Vu :2 445

Auteur : chris_brabant

Ecrire un message privé
Commentaire sur cette source (2)
Ajouter un commentaire et/ou une note

 Description

Voici un exemple concret qui illustre l'utilisation de l'API Win32 'SendMessage' entre deux applications VB.NET :
   - premièrement un programme 'client' qui envoie un message
   - deuxièmement un programme 'serveur' qui écoute les messages

Le programme 'client'
=====================
Il utilise l'API SendMessage, mais également WriteProcessMemory et VirtualAllocEx.
Deux cas sont codés, mais toutes les combinaisons sont possibles :
   - 1er cas : numéro de message 100255 : un entier est envoyé dans le paramètre wParam, et une chaine de caractères ANSI est envoyée dans le paramètre lParam
   - 2ème cas : numéro de message 100355 : un entier est envoyé dans le paramètre wParam, et une structure est envoyée dans le paramètre lParam ; la structure contient 3 champs : 1 Double, une chaine de caractères ANSI, et un entier

La cible du SendMessage est l'ID de la fenêtre principale du programme 'serveur'. Il est obtenu en recherchant parmi les processus actifs, celui dont la propriété 'MainWindowTitle' contient le titre de la fenêtre principale du programme 'serveur'.

Le programme 'serveur'
======================
C'est une simple WinForm, dans laquelle la boucle d'évènements n'est pas celle par défaut. Elle est remplacée par la procédure 'WndProc'. Elle reçoit tous les messages qui sont envoyés à la fenêtre, y compris nos messages utilisateur 100255 et 100355.
Ainsi nos messages utilisateur 100255 et 100355 peuvent être traités particulièrement, et tous les autres messages sont transmis tels quels à la fenêtre.

Source

  • Client
  • ======
  • Imports System.Runtime.InteropServices
  • Public Class MyWinForm
  • Enum AllocationType
  • Commit = &H1000
  • Reserve = &H2000
  • Decommit = &H4000
  • Release = &H8000
  • Reset = &H80000
  • Physical = &H400000
  • TopDown = &H100000
  • WriteWatch = &H200000
  • LargePages = &H20000000
  • End Enum
  • Enum MemoryProtection
  • Execute = &H10
  • ExecuteRead = &H20
  • ExecuteReadWrite = &H40
  • ExecuteWriteCopy = &H80
  • NoAccess = &H1
  • ReadOnlyFlag = &H2
  • ReadWrite = &H4
  • WriteCopy = &H8
  • GuardModifierFlag = &H100
  • NoCacheModifierFlag = &H200
  • WriteCombineModifierFlag = &H400
  • End Enum
  • ' Win32 déclarations
  • Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
  • (ByVal hWnd As IntPtr, ByVal wCmd As Integer, _
  • ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
  • Declare Function WriteProcessMemory Lib "kernel32.dll" _
  • (ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, _
  • ByVal lpBuffer As IntPtr, ByVal nSize As Integer, _
  • ByVal lpNumberOfBytesWritten As IntPtr) As IntPtr
  • Declare Function VirtualAllocEx Lib "kernel32.dll" _
  • (ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, _
  • ByVal dwSize As UInteger, ByVal flAllocationType As AllocationType, _
  • ByVal flProtect As MemoryProtection) As IntPtr
  • Private Structure MyStructure
  • Dim ddd As Double
  • Dim sss As IntPtr ' For Ansi String
  • Dim iii As Integer
  • End Structure
  • Private Const TARGET_WINDOW_TITLE As String = "MyWindow" ' For example !
  • Private Sub btnStructureBySendMessage_Click(ByVal sender As System.Object, _
  • ByVal e As System.EventArgs) Handles btnStructureBySendMessage.Click
  • Try
  • Dim local_processes() As Process = Process.GetProcesses()
  • If local_processes.Length > 0 Then
  • For Each p As Process In local_processes
  • If p.MainWindowTitle = TARGET_WINDOW_TITLE Then
  • Dim my_struct As MyStructure
  • my_struct.ddd = 100.28 ' For example !
  • my_struct.iii = 258955 ' For example !
  • Dim ansi_str As String = "hello world !"
  • Dim ansi_len As Integer = Marshal.SizeOf("c"c) * ansi_str.Length
  • Dim str_ptr As IntPtr = VirtualAllocEx(p.Handle, IntPtr.Zero, _
  • CUInt(ansi_len), _
  • AllocationType.Commit, MemoryProtection.ReadWrite)
  • my_struct.sss = str_ptr
  • Dim tmp_str_ptr As IntPtr = Marshal.StringToHGlobalAnsi(ansi_str)
  • WriteProcessMemory(p.Handle, str_ptr, tmp_str_ptr, ansi_len, IntPtr.Zero)
  • Marshal.FreeHGlobal(tmp_str_ptr)
  • Dim tmp_struct_ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(my_struct))
  • Marshal.StructureToPtr(my_struct, tmp_struct_ptr, True)
  • Dim my_struct_ptr As IntPtr = VirtualAllocEx(p.Handle, IntPtr.Zero, _
  • CUInt(Marshal.SizeOf(GetType(MyStructure))), _
  • AllocationType.Commit, MemoryProtection.ReadWrite)
  • WriteProcessMemory(p.Handle, my_struct_ptr, tmp_struct_ptr, _
  • Marshal.SizeOf(my_struct), IntPtr.Zero)
  • Marshal.FreeHGlobal(tmp_struct_ptr)
  • Dim w_param As New IntPtr(15) ' For example !
  • Dim sm_res As IntPtr = _
  • SendMessage(p.MainWindowHandle, 100355, w_param, my_struct_ptr)
  • Exit For
  • End If
  • Next
  • End If
  • Catch ex As Exception
  • MessageBox.Show(ex.Message)
  • End Try
  • End Sub
  • Private Sub btnSendAnsiString_Click(ByVal sender As System.Object, _
  • ByVal e As System.EventArgs) Handles btnSendAnsiString.Click
  • Try
  • Dim local_processes() As Process = Process.GetProcesses()
  • If local_processes.Length > 0 Then
  • For Each p As Process In local_processes
  • If p.MainWindowTitle = TARGET_WINDOW_TITLE Then
  • Dim ansi_str As String = "look at this my friends ..." ' For example !
  • Dim ansi_len As Integer = Marshal.SizeOf("c"c) * ansi_str.Length
  • Dim str_ptr As IntPtr = VirtualAllocEx(p.Handle, IntPtr.Zero, _
  • CUInt(ansi_len), _
  • AllocationType.Commit, MemoryProtection.ReadWrite)
  • Dim tmp_str_ptr As IntPtr = Marshal.StringToHGlobalAnsi(ansi_str)
  • WriteProcessMemory(p.Handle, str_ptr, tmp_str_ptr, ansi_len, IntPtr.Zero)
  • Marshal.FreeHGlobal(tmp_str_ptr)
  • Dim w_param As New IntPtr(255) ' For example !
  • Dim sm_res As IntPtr = _
  • SendMessage(p.MainWindowHandle, 100255, w_param, str_ptr)
  • Exit For
  • End If
  • Next
  • End If
  • Catch ex As Exception
  • MessageBox.Show(ex.Message)
  • End Try
  • End Sub
  • End Class
  • serveur
  • =======
  • Public Class frmAccueil
  • Private Structure MyStructure
  • Dim ddd As Double
  • Dim sss As IntPtr ' For Ansi String
  • Dim iii As Integer
  • End Structure
  • Protected Overrides Sub WndProc(ByRef m As Message)
  • Select Case (m.Msg)
  • Case 100255 ' A String should be sent
  • ' First thing : we get the integer value stored in wParam
  • Dim i As Integer = m.WParam.ToInt32
  • Console.WriteLine("wParam is : '" + i.ToString + "'")
  • ' Second thing : lParam pointer must be converted to ansi String
  • Dim ansi_str As String = Marshal.PtrToStringAnsi(m.LParam)
  • Console.WriteLine("lParam is : '" + ansi_str + "'")
  • Case 100355 ' A Structure should be sent
  • ' First thing : we get the integer value stored in wParam
  • Dim i As Integer = m.WParam.ToInt32
  • Console.WriteLine("wParam is : " + i.ToString)
  • ' Second thing : lParam pointer must be converted to structure
  • Dim o As Object = Marshal.PtrToStructure(m.LParam, GetType(MyStructure))
  • Dim my_struct As MyStructure = CType(o, MyStructure)
  • ' Third thing : 'sss' field of structure must be converted to ansi String
  • Dim ansi_sss As String = Marshal.PtrToStringAnsi(my_struct.sss)
  • Console.WriteLine("lParam is : ddd='" + my_struct.ddd.ToString + "'" _
  • + " sss='" + ansi_sss.ToString + "'" _
  • + " iii='" + my_struct.iii.ToString + "'")
  • End Select
  • MyBase.WndProc(m) ' very important !
  • End Sub
  • End Class
Client
======

Imports System.Runtime.InteropServices

Public Class MyWinForm

    Enum AllocationType
        Commit = &H1000
        Reserve = &H2000
        Decommit = &H4000
        Release = &H8000
        Reset = &H80000
        Physical = &H400000
        TopDown = &H100000
        WriteWatch = &H200000
        LargePages = &H20000000
    End Enum

    Enum MemoryProtection
        Execute = &H10
        ExecuteRead = &H20
        ExecuteReadWrite = &H40
        ExecuteWriteCopy = &H80
        NoAccess = &H1
        ReadOnlyFlag = &H2
        ReadWrite = &H4
        WriteCopy = &H8
        GuardModifierFlag = &H100
        NoCacheModifierFlag = &H200
        WriteCombineModifierFlag = &H400
    End Enum

    ' Win32 déclarations

    Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
        (ByVal hWnd As IntPtr, ByVal wCmd As Integer, _
        ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

    Declare Function WriteProcessMemory Lib "kernel32.dll" _
        (ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, _
        ByVal lpBuffer As IntPtr, ByVal nSize As Integer, _
        ByVal lpNumberOfBytesWritten As IntPtr) As IntPtr

    Declare Function VirtualAllocEx Lib "kernel32.dll" _
        (ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, _
        ByVal dwSize As UInteger, ByVal flAllocationType As AllocationType, _
        ByVal flProtect As MemoryProtection) As IntPtr

    Private Structure MyStructure
        Dim ddd As Double
        Dim sss As IntPtr   ' For Ansi String
        Dim iii As Integer
    End Structure

    Private Const TARGET_WINDOW_TITLE As String = "MyWindow"    ' For example !

    Private Sub btnStructureBySendMessage_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnStructureBySendMessage.Click

        Try

            Dim local_processes() As Process = Process.GetProcesses()

            If local_processes.Length > 0 Then
                For Each p As Process In local_processes
                    If p.MainWindowTitle = TARGET_WINDOW_TITLE Then

                        Dim my_struct As MyStructure
                        my_struct.ddd = 100.28  ' For example !
                        my_struct.iii = 258955  ' For example !

                        Dim ansi_str As String = "hello world !"
                        Dim ansi_len As Integer = Marshal.SizeOf("c"c) * ansi_str.Length

                        Dim str_ptr As IntPtr = VirtualAllocEx(p.Handle, IntPtr.Zero, _
                            CUInt(ansi_len), _
                            AllocationType.Commit, MemoryProtection.ReadWrite)

                        my_struct.sss = str_ptr

                        Dim tmp_str_ptr As IntPtr = Marshal.StringToHGlobalAnsi(ansi_str)

                        WriteProcessMemory(p.Handle, str_ptr, tmp_str_ptr, ansi_len, IntPtr.Zero)
                        Marshal.FreeHGlobal(tmp_str_ptr)

                        Dim tmp_struct_ptr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(my_struct))
                        Marshal.StructureToPtr(my_struct, tmp_struct_ptr, True)

                        Dim my_struct_ptr As IntPtr = VirtualAllocEx(p.Handle, IntPtr.Zero, _
                            CUInt(Marshal.SizeOf(GetType(MyStructure))), _
                            AllocationType.Commit, MemoryProtection.ReadWrite)

                        WriteProcessMemory(p.Handle, my_struct_ptr, tmp_struct_ptr, _
                            Marshal.SizeOf(my_struct), IntPtr.Zero)
                        Marshal.FreeHGlobal(tmp_struct_ptr)

                        Dim w_param As New IntPtr(15)   ' For example !

                        Dim sm_res As IntPtr = _
                            SendMessage(p.MainWindowHandle, 100355, w_param, my_struct_ptr)

                        Exit For
                    End If
                Next
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub btnSendAnsiString_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnSendAnsiString.Click

        Try

            Dim local_processes() As Process = Process.GetProcesses()

            If local_processes.Length > 0 Then
                For Each p As Process In local_processes
                    If p.MainWindowTitle = TARGET_WINDOW_TITLE Then

                        Dim ansi_str As String = "look at this my friends ..."  ' For example !
                        Dim ansi_len As Integer = Marshal.SizeOf("c"c) * ansi_str.Length

                        Dim str_ptr As IntPtr = VirtualAllocEx(p.Handle, IntPtr.Zero, _
                            CUInt(ansi_len), _
                            AllocationType.Commit, MemoryProtection.ReadWrite)

                        Dim tmp_str_ptr As IntPtr = Marshal.StringToHGlobalAnsi(ansi_str)

                        WriteProcessMemory(p.Handle, str_ptr, tmp_str_ptr, ansi_len, IntPtr.Zero)
                        Marshal.FreeHGlobal(tmp_str_ptr)

                        Dim w_param As New IntPtr(255)  ' For example !

                        Dim sm_res As IntPtr = _
                            SendMessage(p.MainWindowHandle, 100255, w_param, str_ptr)

                        Exit For
                    End If
                Next
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

    End Sub
End Class


serveur
=======

Public Class frmAccueil

    Private Structure MyStructure
        Dim ddd As Double
        Dim sss As IntPtr   ' For Ansi String
        Dim iii As Integer
    End Structure

    Protected Overrides Sub WndProc(ByRef m As Message)

        Select Case (m.Msg)
            Case 100255 ' A String should be sent

                ' First thing : we get the integer value stored in wParam
                Dim i As Integer = m.WParam.ToInt32

                Console.WriteLine("wParam is : '" + i.ToString + "'")

                ' Second thing : lParam pointer must be converted to ansi String
                Dim ansi_str As String = Marshal.PtrToStringAnsi(m.LParam)

                Console.WriteLine("lParam is : '" + ansi_str + "'")

            Case 100355 ' A Structure should be sent

                ' First thing : we get the integer value stored in wParam
                Dim i As Integer = m.WParam.ToInt32

                Console.WriteLine("wParam is : " + i.ToString)

                ' Second thing : lParam pointer must be converted to structure
                Dim o As Object = Marshal.PtrToStructure(m.LParam, GetType(MyStructure))
                Dim my_struct As MyStructure = CType(o, MyStructure)

                ' Third thing : 'sss' field of structure must be converted to ansi String
                Dim ansi_sss As String = Marshal.PtrToStringAnsi(my_struct.sss)

                Console.WriteLine("lParam is : ddd='" + my_struct.ddd.ToString + "'" _
                    + " sss='" + ansi_sss.ToString + "'" _
                    + " iii='" + my_struct.iii.ToString + "'")

        End Select

        MyBase.WndProc(m)   ' very important !

    End Sub
End Class

 Conclusion

Illustration de la cohabitation entre du code managé et non managé, et du Marshaling.

Amélioration : tester tous les codes retour des API.

Bon courage !


 Historique

23 mai 2012 11:05:32 :
correction de deux fautes

 Sources du même auteur

Source avec Zip Source avec une capture Source .NET (Dotnet) LIRE ET GÉNÉRER UN FICHIER DBASE AVEC UN CODE 100% .NET
Source avec Zip Source avec une capture Source .NET (Dotnet) COMBOBOX MULTI COLONNES
Source avec Zip Source .NET (Dotnet) GARDER LA SÉLECTION DANS UN DATAGRID APRÈS LE TRI SUR UNE CO...
Source avec Zip Source avec une capture Source .NET (Dotnet) CLASSES PERMETTANT DE FAIRE "CLIGNOTER" LES COLONNES D'UN DA...
Source avec Zip Source avec une capture Source .NET (Dotnet) REDIMENSIONNER LES COLONNES D'UN CONTRÔLE DATAGRID D'APRÈS S...

 Sources de la même categorie

Source avec Zip Source .NET (Dotnet) CONVERSION DE LA BASE 2 À LA BASE 10 par alpha5
Source avec Zip Source .NET (Dotnet) SURVEILLANCE ÉVÈNEMENT par mimiZanzan
Source avec Zip Source avec une capture BOT TYPE CHAINE DE MARKOV ( ACTOR PAR EXEMPLE) par buron
Source .NET (Dotnet) VB.NET CAMERA VIDEO par moezzeom
Source avec Zip Source avec une capture Source .NET (Dotnet) CARNET D'ADRESSE par colby

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture Source .NET (Dotnet) CLASSE DÉFINISSANT TOUTES LES CONSTANTES WINDOWS MESSAGE (WM... par XDarwin
Source avec Zip COURS DE PILOTAGE........D'APPLICATIONS par Renfield
Source avec Zip COMMUNICATION INTER-PROCESSUS (IPC) par MadM@tt
Source avec Zip Source avec une capture EXTRAIRE LE TEXTE DES FENETRES D'APPLICATIONS TIERCES (LISTB... par Renfield
Source .NET (Dotnet) ECRIRE OU LIRE UNE STRUCTURE DANS UN FICHIER BINAIRE par Picpic10

Commentaires et avis

Commentaire de MiharbiDoNo le 25/05/2012 02:29:25

je trouve ça beau, je te conseille juste de lire ceci : http://support.microsoft.com/kb/86835

Commentaire de chris_brabant le 30/05/2012 11:34:51

les numéros de messages que j'ai indiqués sont pris au hasard, j'aurais du mettre des valeurs supérieures à WM_APP (32768) et inférieures à  0xFFFF (65535).

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

SendMessage [ par Patrice ] Est-ce qqun peut me dire comment utiliser l'api sendmessage avec comme paramètre WM_GETTEXT.Merci d'avance. Connaître le scrollMax d'un contrôle Treeview [ par stephane ] Pour mon application, je met en place une routine pour imprimer la totalité d'un treeview. Pour cela, je fais défilier le treeview à l'aide de l'api s SendMessage - W2000 [ par Christophe ] Bonjour,Sous Windows 2000, est-ce la même déclaration ? :Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hwnd As Intege Constante pour SendMessage [ par Johjo ] Je voudrais obtenir les constantes qui permettent à SendMessage de renvoyer les numéros de lignes et de colonne utilisation de l'API SendMessage avec LB_SETHORIZONTALEXTENT et LB_SETVERTICALEXTENT [ par seedorf ] Qq1 connait comment on utilise l'api SendMessage avec les parametres LB_SETHORIZONTALEXTENT et LB_SETVERTICALEXTENT pour ENLEVE les barre de défilleme Comment trouver un item dans un imagecombo [ par Steph ] Comment trouver un item dans un imagecombo de la même manière qu'un combobox traditionnel par la méthode sendmessageDeclare Function SendMessage Lib " SendMessage tjrs un bleme :( [ par Niaphron ] Bonjour, je voudrais savoir comment envoyé à une fenetre la touche TAB par l'internédiaire de la commande sendMessage ??? L'api : SendMessage - WM_CLOSE ne ferme pas IE ! [ par magicyoda ] ca menerve ! cette fonction ne ferme pas IE !jai trouve sur le site une api : destroywindow mais elle marchait avec aucun programme !je voudrais bien sendmessage HELP [ par Pof ] READPROCESSMEMORY et WRITEPROCESSMEMORY !!! [ par TheBabyCool ] Quelqu'un pourait par un court exemple m'expliquer comment utiliser les apis READPROCESSMEMORY et WRITEPROCESSMEMORY.MERCI infinimentDorian


Nos sponsors


Sondage...

CalendriCode

Juin 2013
LMMJVSD
     12
3456789
10111213141516
17181920212223
24252627282930

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,874 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales