Accueil > > > UTILISATION DE L'API SENDMESSAGE ENTRE DEUX APPLICATIONS VB.NET
UTILISATION DE L'API SENDMESSAGE ENTRE DEUX APPLICATIONS VB.NET
Information sur la source
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
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
INTéGRATION YAMMER ET SHAREPOINT ONLINE (OFFICE 365), éTAPE 1 .INTéGRATION YAMMER ET SHAREPOINT ONLINE (OFFICE 365), éTAPE 1 . par Patrick Guimonet
#Yammer Certains s'en sont déjà fait l'écho (ici en allemand par exemple : Yammer Integration in Office 365 Phase 1) ou bien sûr sur le blog SharePoint : Make Yammer your default social network in Office 365 en anglais. Mais c'e...
Cliquez pour lire la suite de l'article par Patrick Guimonet [DYNAMICS CRM] AJOUTER LES DOSSIERS DE CRM AU DOSSIER FAVORIS D'OUTLOOK[DYNAMICS CRM] AJOUTER LES DOSSIERS DE CRM AU DOSSIER FAVORIS D'OUTLOOK par bianca
Objectif
Pour aller plus rapidement dans les menus de Dynamics CRM depuis votre client CRM pour Outlook, vous pouvez utiliser le dossier des Favoris d'Outlook. En effet, par simple glisser/déplacer, vous pouvez déposer un éléme...
Cliquez pour lire la suite de l'article par bianca VISUAL STUDIO 2013VISUAL STUDIO 2013 par Etienne Margraff
Ahh, ENFIN ! c'est officiel, il va y avoir un VS et un TFS 2013. De nouvelles fonctionnalités qui vont à mon sens assoir la maturité de TFS qui est maintenant l'outil incontournable pour tout projet (.NET, mais pas seulement !). Si vous n'avez pas jet...
Cliquez pour lire la suite de l'article par Etienne Margraff CONFIGURER LA COLLATION SQL SERVER POUR SHAREPOINT CONFIGURER LA COLLATION SQL SERVER POUR SHAREPOINT par JeremyJeanson
Note : Je poste cet article à titre de pense-bête. Cela fait des années que je me trimballe avec une capture d'écran, car je ne me rappel jamais comment choisir la collation d'un SQL Server pour SharePoint. Pour SharePoint, il est conseillé de choisir la ...
Cliquez pour lire la suite de l'article par JeremyJeanson ETENDRE LE TEAM WEB ACCESS DE TFS 2012 - STEP 1: CRéATION DU PLUGINETENDRE LE TEAM WEB ACCESS DE TFS 2012 - STEP 1: CRéATION DU PLUGIN par Philess
Dans cet article nous allons créer un plugin installable sur le Team Web Access qui s'intègrera dans l'architecture du site et se chargera au moment où on le décidera.
Avant de lire ce billet et si cela n'est pas encore fait j...
Cliquez pour lire la suite de l'article par Philess
Logiciels
Nego Facturation (1.85)NEGO FACTURATION (1.85)Nego Facturation est un logiciel complet qui permet de gérer vos factures et devis très simplemen... Cliquez pour télécharger Nego Facturation Devis-Factures PHMSD (2.2.0.1)DEVIS-FACTURES PHMSD (2.2.0.1)Configuration minimale
Nécessite Windows™ 2000, XP, Windows 7, 8, Vista (Service Pack à... Cliquez pour télécharger Devis-Factures PHMSD WDmemoCode (2.0.0.1)WDMEMOCODE (2.0.0.1)WDmemoCode a été conçu pour aider les développeurs Windev à créer/compléter et conserver une base... Cliquez pour télécharger WDmemoCode ProtoMedic (4.0.0.11)PROTOMEDIC (4.0.0.11)ProtoMedic est un logiciel destiné principalement aux médecins généralistes.
ProtoMedic permet d... Cliquez pour télécharger ProtoMedic MyCurriculum 2011 (7.4.1.12)MYCURRICULUM 2011 (7.4.1.12)Rédigez votre Curriculum Vitae mais également ceux de votre famille ou de vos amis très facilemen... Cliquez pour télécharger MyCurriculum 2011
|