bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 2019
-
19 sept. 2006 à 08:49
pradier4
Messages postés4Date d'inscriptiondimanche 9 octobre 2011StatutMembreDernière intervention24 août 2012
-
24 août 2012 à 13:42
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
pradier4
Messages postés4Date d'inscriptiondimanche 9 octobre 2011StatutMembreDernière intervention24 août 2012 24 août 2012 à 13:42
Quelle différence entre StreamChanged et FireEvent?
pradier4
Messages postés4Date d'inscriptiondimanche 9 octobre 2011StatutMembreDernière intervention24 août 2012 24 août 2012 à 13:22
Je voudrais bien aussi avoir un moyen d'agrandir la taille
Merci
LaTatadu91
Messages postés968Date d'inscriptionjeudi 20 mai 2004StatutMembreDernière intervention26 avril 20131 24 août 2012 à 13:20
Oui bien sûr il faut changer la MAPSIZE, en fait mon code est en C++, je dois échanger des structures assez lourdes et j'arrive à un total de plusieurs Mo (8 je crois) ça marche mais je me demandais vu que mon échange est régulier (toutes les minutes) si ça tiendrait le coup sur la longueur.
pradier4
Messages postés4Date d'inscriptiondimanche 9 octobre 2011StatutMembreDernière intervention24 août 2012 24 août 2012 à 13:12
Mais quelle différence avec StreamChanged?
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 24 août 2012 à 10:18
LATATADU91>>Dans le principe pas de taille limite.
Attention quand même à ne pas saturer la mémoire vive au risque d'avoir quelques ralentissements :-)
Pour la grande quantité de données de quoi s'agit-il ?
Le code n'a pas été prévu pour ça : variable Stream de type String.
Il faudra aussi revoir la variable MAPSIZE (16 Ko par défaut).
Avec un peu d'effort cela doit être possible.
PRADIER4>>FireEvent permet de SubClasser la variable. En gros ton appli est avertit dès que la variable est modifiée. Donc nul besoin de timer.
LaTatadu91
Messages postés968Date d'inscriptionjeudi 20 mai 2004StatutMembreDernière intervention26 avril 20131 24 août 2012 à 09:41
Petite question: Y a t'il une limite à la taille du message? est ce que une taille de plusieurs Mo serait susceptible de créer des dysfonctionnements?
Sinon, encore merci ce code m'a été très utile.
pradier4
Messages postés4Date d'inscriptiondimanche 9 octobre 2011StatutMembreDernière intervention24 août 2012 23 août 2012 à 19:51
Bonjour, quelqu'un pourrait m'expliquer la fonction fireevent.
Par ailleurs, y a til un moyen de savoir si un autre logiciel est présent sur cette zone mémoire? Avec un code envoyé tous les 1/1000 secondes par un timer et quand ya plus c qu'il est plus là?
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 9 févr. 2012 à 18:39
code basé principalement sur APIs Windows ; la traduction devrait aller simplement.
si souci, me contacter (faudra peut etre simplifier en retirant le cryptage, par exemple)
LaTatadu91
Messages postés968Date d'inscriptionjeudi 20 mai 2004StatutMembreDernière intervention26 avril 20131 9 févr. 2012 à 16:14
Très bon code! Il me sera très utile ... une fois traduit en C++ !
rvs76
Messages postés6Date d'inscriptionmercredi 20 août 2003StatutMembreDernière intervention 3 novembre 2011 29 mars 2011 à 20:06
je répond à moi même : il faut aussi changer le string de RegisterWindowsMessage
Public Sub New(ByVal Nom As NomPredefini)
Dim NomFichier As String = Nom.ToString
meMsgStreamChanged = RegisterWindowMessage("InterProcess_StreamChanged" & Nom)
'meMsgCustomEvent = RegisterWindowMessage("InterProcess_CustomEvent")
'mhMap = OpenFileMapping(FILE_MAP_READ Or FILE_MAP_WRITE, 0, MAPKEY)
mhMap = OpenFileMapping(FILE_MAP_READ Or FILE_MAP_WRITE, 0, NomFichier)
Dim tp As CreateParams = New CreateParams()
tp.ClassName = "STATIC"
CreateHandle(tp)
If mhMap = 0 Then
' mhMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, MAPSIZE, MAPKEY)
mhMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, MAPSIZE, NomFichier)
If mhMap <> 0 Then
Dim pMem As IntPtr = MapViewOfFile(mhMap, FILE_MAP_WRITE, 0, 0, 0)
If pMem <> IntPtr.Zero Then
ZeroMemory(pMem, MAPSIZE)
UnmapViewOfFile(pMem)
End If
End If
End If
End Sub
NomPredefini du constructeur est un enum pour nommer mes trois "tuyaux".
rvs76
Messages postés6Date d'inscriptionmercredi 20 août 2003StatutMembreDernière intervention 3 novembre 2011 29 mars 2011 à 15:50
Bonjour,
Je déterre un peu ce code en espérant qu'on me réponde.
Voila, j'ai trois applis (indépendantes) en VB.NET avec des base de données qui contiennent des données proches et/ou complémentaires. J'ai créé une quatrième appli qui contient une autre bdd avec juste les mappages des trois autres bases ainsi que plusieurs fenêtres.
J'utilise cette source légèrement modifié afin d'avoir trois noms différents de fichier virtuel et trois objet IP dans la quatrième appli.
Chaque "tuyau" est bien isolé, mais le problème est que les évènements StreamChanged qui se mélangent dans la quatrième appli. Par exemple, si du texte est envoyé de l'appli_1 vers l'appli_4, c'est le tuyau_3 qui déclenche l'évènement StreamChanged dans l'appli_4 (dernier tuyau créé ?) mais le stream du tuyau_3 est vide.
Si quelqu'un peut m'aider...
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 28 déc. 2009 à 22:16
ok.
du coup, ca allait pour partager des variables, mais le temps reel en patissait...
bon diagnostic et bonne resolution, une fois encore
cs_DarkVader
Messages postés51Date d'inscriptionsamedi 21 octobre 2000StatutMembreDernière intervention10 octobre 2011 28 déc. 2009 à 18:20
Un blem mineur dans l'actualisation des données, pour peu que plusieurs écriture/lecture de données soient alternées
ex
Private WithEvents classIP As InterProcess
Private Sub Class_Initialize()
Set classIP = New InterProcess
With classIP
printVar classIP
.VarValue("Var1") = "test3"
printVar classIP
.VarValue("Var2") = "True4"
printVar classIP
End With
End Sub
Private Sub Class_Terminate()
Set classIP = Nothing
End Sub
Private Sub classIP_Changed(ByVal vnIndex As Long)
Debug.Print " --- classIP_Changed(ByVal " & vnIndex & " As Long): " & classIP.VarName(vnIndex) & " => " & classIP.VarValue(vnIndex)
End Sub
Private Sub printVar(oClass As Object)
Dim x As Long
With oClass
Debug.Print String(13, "=") & " " & .VarCount & " " & String(13, "=") & vbCrLf
For x = 0 To .VarCount - 1
Debug.Print x, .VarName(x), .VarValue(x)
Next
End With
Debug.Print String(30, "-") & vbCrLf
End Sub
Résultat inattendu !
Un simple doevents placé après le Postmessage HWND_BROADCAST résoud le problème. 8)
Bonnes fêtes de fin d'année.
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 17 déc. 2009 à 13:26
Salut
Je me permet de relancer concernant ma question sur le OpenFileMapping
Merci d'avance
++
cs_DarkVader
Messages postés51Date d'inscriptionsamedi 21 octobre 2000StatutMembreDernière intervention10 octobre 2011 17 déc. 2009 à 12:33
Si beaucoup ne s'exprime en général pas ,
le nombre de téléchargement est tout de même la preuve que ta source ne laisse pas indifférent. 8)
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 17 déc. 2009 à 12:26
Fait, cool de voir que cette source est utile à certains
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 17 déc. 2009 à 12:19
Bonne remarque, correction adaptée....
je repiques l'idée et mets a jour rapidement
cs_DarkVader
Messages postés51Date d'inscriptionsamedi 21 octobre 2000StatutMembreDernière intervention10 octobre 2011 17 déc. 2009 à 12:16
Il y a un os dans le potage.
Je vais regretter de t'avoir mis un 10 lol
Quid quand la valeur insérée est une chaine vide ?
J'ai contourné en remplaçant vbNullChar & vbNullChar par Chr(0) & Chr(255).
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 14 déc. 2009 à 15:05
Dans le cadre de mon logiciel de GED.
Lors de la consultation d'une archive, aujourd'hui je dois :
- extraire le stream de la BDD
- le placer dans un fichier temporaire
- ouvrir le fichier
- surveiller sa fermeture
- supprimer le fichier du disque
Cette opération me ferait gagner un temps précieux en économisant les accès disque.
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 14 déc. 2009 à 14:45
Bouv, je vois pas l'interet de ta question...
si tu as un vrai fichier, pourquoi vouloir ouvrir son filemapping ?
cs_DarkVader
Messages postés51Date d'inscriptionsamedi 21 octobre 2000StatutMembreDernière intervention10 octobre 2011 14 déc. 2009 à 12:26
Bonjour
C'est superbe Renfield - que du bonheur dans cette source,
qui en plus est distribuée sous VB6 et VB.net.
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 8 déc. 2009 à 17:15
Salut,
J'ai une question qui peut paraître absurde mais je la pose quand même.
Admettons que je place le Stream d'un vrai fichier dans le FileMapping (celui d'un pdf par exemple).
Peut-on ensuite appeler un substitut de la fonction FileOpen sur ce FileMapping pour l'ouvrir dans le prog par défaut ?
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 4 déc. 2009 à 19:01
a noter qu'il vaut mieux personnaliser (GUID ?) les mots en clair (passés a RegisterWindowMessage et le MAPKEY)
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 4 déc. 2009 à 16:40
du coup j'ai ajouté en .Net le 'FireEvent'
comme ça, on communique plus efficacement entre processus ^^
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 4 déc. 2009 à 16:36
Tu l'as dit bouffi... le subclassing en .Net est un vrai bonheur comme beaucoup d'autres choses. Si bien que je n'utilise plus du tout VB6 (même pas installé).
++
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 4 déc. 2009 à 16:21
Elle est basique (simple stream)
mais le subclassing avec NativeWindow est un vrai régal !
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 4 déc. 2009 à 16:16
Merci pour la version .Net je vais essayer
++
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 4 déc. 2009 à 14:42
j'ai (encore) mis a jour mon code :
j'y ai inclus une version .Net certes allégée, mais plus simple a comprendre.
ici, on partage un bête flux texte (16Ko)
on a un evenement StreamChanged
pour le jeu du Dictionary fait en VB6, libre à vous de jouer a (dé)serialiser ce que vous voulez, comme vous le voulez ^^
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 3 déc. 2009 à 15:23
GROSSE mise a jour, la classe se tourne davantage vers une communication inter-process complète, avec la possibilité de propager des evènements personnalisés dans toutes les isntances de la classe
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 2 déc. 2009 à 23:57
Je viens d'ajouter un evenement (via subclassing) qui permet de savoir quand le contenu de la mémoire partagée a changé
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 2 juil. 2008 à 15:20
version .NET : (pas forcément optimale, hein, je tatonne ^^)
mais ca fonctionne...
Imports System.Runtime.InteropServices
Public Class SharedValues
' Pour que plusieurs programmes puissent échanger ces valeurs, il suffit de modifier la clé ci dessous :
Private Const MAPKEY As String = "SharedValues"
' Taille du tampon (8 Ko)
Private Const MAPSIZE = &H2000&
Private Const SECTION_MAP_READ As Integer = &H4
Private Const SECTION_MAP_WRITE As Integer = &H2
Private Const FILE_MAP_READ As Integer = SECTION_MAP_READ
Private Const FILE_MAP_WRITE As Integer = SECTION_MAP_WRITE
Private Const INVALID_HANDLE_VALUE As Integer = &HFFFFFFFF
Private Const PAGE_READWRITE As Integer = &H4
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Integer) As Integer
Private Declare Function CreateFileMapping Lib "kernel32.dll" Alias "CreateFileMappingA" (ByVal hFile As Integer, ByVal lpFileMappingAttributes As Integer, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer
Private Declare Function MapViewOfFile Lib "kernel32.dll" (ByVal hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As Integer
Private Declare Function OpenFileMapping Lib "kernel32.dll" Alias "OpenFileMappingA" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal lpName As String) As Integer
Private Declare Function UnmapViewOfFile Lib "kernel32.dll" (ByRef lpBaseAddress As IntPtr) As Integer
Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" (ByVal Destination As IntPtr, ByVal Length As Integer)
Private mhMap As Integer
Private msName As String
Private mnSize As Integer
Public ReadOnly Property Name() As String
Get
Name = msName
End Get
End Property
Public ReadOnly Property Size() As Integer
Get
Size = mnSize
End Get
End Property
Public Sub New()
Load(MAPKEY, MAPSIZE)
End Sub
Public Sub New(ByRef vsName As String)
Load(vsName, MAPSIZE)
End Sub
Public Sub New(ByVal vnSize As Integer)
Load(MAPKEY, vnSize)
End Sub
' Cette méthode permet de changer de mappage, ou de changer la taille de celui-ci...
Public Sub New(ByRef vsName As String, ByVal vnSize As Integer)
Load(vsName, vnSize)
End Sub
Private Sub Load(ByRef vsName As String, ByVal vnSize As Integer)
Dim pMem As IntPtr
' Si un mappage est ouvert, on le ferme...
If mhMap Then
CloseHandle(mhMap)
End If
' On enregistre le nom du mappage
msName = vsName
' Et on tente d'ouvrir le mappage
mhMap = OpenFileMapping(FILE_MAP_READ Or FILE_MAP_WRITE, 0, msName)
If mhMap = 0 Then
' Le mappage n'existe pas ?
' Nous allons donc le créer. Il aura la taille demandée par l'utilisateur.
mnSize = vnSize
' Création du mappage
mhMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, mnSize, msName)
If mhMap Then
' Le premier Integer dans le fichier sera la taille du mappage.
' Tout le reste est remplit par des 0
pMem = MapViewOfFile(mhMap, FILE_MAP_WRITE, 0, 0, 0)
If pMem Then
Marshal.WriteInt32(pMem, 0, mnSize)
ZeroMemory(New IntPtr(pMem.ToInt32 + 4), mnSize - 4)
UnmapViewOfFile(pMem)
End If
End If
Else
' Le mappage existe déjà. Nous lisons la taille de celui-ci
pMem = MapViewOfFile(mhMap, FILE_MAP_READ, 0, 0, 0)
If pMem Then
mnSize = Marshal.ReadInt32(pMem, 0)
UnmapViewOfFile(pMem)
End If
End If
End Sub
Public Sub Unload()
' Fermeture du mappage
If mhMap Then
CloseHandle(mhMap)
mhMap = 0
End If
End Sub
' Permet de récupérer une valeur en particulier du Stream.
Public Property Value(ByVal vsName As String) As String
Get
Value = vbNullString
Try
For Each sPair As String In Stream.Split(vbNullChar)
If sPair.StartsWith(vsName & "=") Then
Value = sPair.Substring(vsName.Length + 1)
Exit For
End If
Next sPair
Catch e As NullReferenceException
End Try
End Get
Set(ByVal value As String)
Try
Dim xsParts() As String = Stream.Split(vbNullChar)
For i As Integer = 0 To xsParts.GetUpperBound(0)
If xsParts(i).StartsWith(vsName & "=") Then
' Sinon, on modifie l'élement de notre tableau
xsParts(i) = vsName & "=" & value
' Et on reconstruit le Stream
Stream = Join(xsParts, vbNullChar)
Exit Property
End If
Next i
Stream = Join(xsParts, vbNullChar) & vbNullChar & vsName & "=" & value
Catch e As NullReferenceException
Stream = vsName & "=" & value
End Try
End Set
End Property
' Permet de récupérer le Stream enregistré dans le mapping
Public Property Stream() As String
Get
Dim pMem As IntPtr
Stream = vbNullString
pMem = MapViewOfFile(mhMap, FILE_MAP_READ, 0, 0, 0)
If pMem Then
' On récupère la taille effective des données
Dim nLength As Integer = Marshal.ReadInt32(pMem, 4)
If nLength > 0 Then
Dim xbData As Char() = New String(" ", nLength).ToCharArray
Marshal.Copy(New IntPtr(pMem.ToInt32 + 8), xbData, 0, nLength)
Stream = New String(xbData, 0, nLength)
End If
UnmapViewOfFile(pMem)
End If
End Get
Set(ByVal value As String)
Dim pMem As IntPtr
pMem = MapViewOfFile(mhMap, FILE_MAP_WRITE, 0, 0, 0)
If pMem Then
Dim xbData As Char() = value.ToCharArray
' On regarde si le mapping est assez grand pour contenir les données
If xbData.Length < mnSize Then
' Tous les autres bits sont remis à 0
ZeroMemory(New IntPtr(pMem.ToInt32 + 8 + xbData.Length), mnSize - 8 - xbData.Length)
' On ajoute la taille des données en début de mapping (après la taille du mapping)
Marshal.WriteInt32(pMem, 4, xbData.Length)
' Et, s'il y a des données, on les ajoutes dans le mapping
If xbData.Length > 0 Then
Marshal.Copy(xbData, 0, New IntPtr(pMem.ToInt32 + 8), xbData.Length)
End If
End If
UnmapViewOfFile(pMem)
End If
End Set
End Property
End Class
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 22 sept. 2006 à 23:04
ASIMENGO>>L'acces au stream est public...
Public Property Get Stream() As String
Public Property Let Stream(ByRef Value As String)
cs_asimengo
Messages postés280Date d'inscriptionjeudi 24 mars 2005StatutMembreDernière intervention18 mars 2009 22 sept. 2006 à 19:16
@Renfield: ça te dirais t'ajouter des fonctions d'enregistrement/restauration du Stream? en espérant que ses infos soient illisibles dans le fichier.
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 22 sept. 2006 à 14:58
Il me semble qu'il y ai un petit problème.
Dans Get Stream, si je met un point d'arret sur
CopyMemory ByVal sBuffer, ByVal pMem + 8, nLength
Je me rend compte que le Buffer est quasiment enregistré en clair. Ou du moins on peut distinguer mon Login et mon Password.
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 22 sept. 2006 à 13:14
MAYZZ ==> Ok ;) Mais la méthode du SaveSettings (pour des sauvegardes temporaires) est quand même assez mauvaise (ajout de clés pas forcément utiles).
@+
Mayzz
Messages postés2813Date d'inscriptionmardi 15 avril 2003StatutMembreDernière intervention 2 juin 202028 22 sept. 2006 à 12:03
violent_ken :
je voulais dire en fait que ça évite de taper les API pour accéder au registre. c'est juste des fonctions incluses dans vb ça évite de taper trop de code =) Dsl je me suis mal exprimé
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 22 sept. 2006 à 10:43
non...
si toutes les instances de la classe ShareValues sont coupées, on perds les infos...
vous pouvez sauvegarder le Stream, et de le restaurer a votre guise
cs_asimengo
Messages postés280Date d'inscriptionjeudi 24 mars 2005StatutMembreDernière intervention18 mars 2009 22 sept. 2006 à 10:36
Par rapport au commentaire de MAYZZ, les clés et valeurs sont-elles conservées même après le redémarrage du PC?
Avec savesetting les clés et valeurs sont retrouvées même après le redémarage du PC.
Le file mapping est-il physique?
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 22 sept. 2006 à 03:54
on peux même en ouvrir un autre (un autre 'MAPKEY')
en utilisant la méthode Load....
reste que quelque soit son nom, en espionnant le logiciel, les APIs utilisées, etc, on pourras toujours trouver que le logiciel ouvre un File mapping (et même en obtenir le contenu).
comme le précise bouv, en ajoutant un Password (par le biai de la propriété du même nom), les données sont cryptées dans le file Mapping.
sans ce Password lors de la lecture...
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 21 sept. 2006 à 23:32
Ahhh ok ^^
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 21 sept. 2006 à 20:57
ASIMENGO>>Il faut connaitre la valeur affectée à MAPKEY pour lire les valeurs. Si tu changes pour
Private Const MAPKEY As String = "MonLogiciel"
Seul celui qui cherche avec la valeur 'MonLogiciel' pourra lire ces données.
MADM@TT>>Renfield à dernièrement ajouté une fonction de cryptage des données pour mieux sécuriser le procédé.
cs_asimengo
Messages postés280Date d'inscriptionjeudi 24 mars 2005StatutMembreDernière intervention18 mars 2009 21 sept. 2006 à 20:42
@Renfield:
'# Pour que plusieurs programmes puissent échanger ces valeurs, il suffit de modifier la clé ci dessous :
Private Const MAPKEY As String = "SharedValues"
Peux-tu être plus clair sur ton commentaire ci-dessus.
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 21 sept. 2006 à 19:07
Ah ouais mais dans ce cas ça crée un problème de sécurité la non ?
car soit y'a moyen de récupérer le mot de passe et le login,soit il s'agit d'une variable boolean genre true : loggé, false : pas loggé, mais dans ce cas y'a surement aussi moyen de récupérer sa valeur et de la modifier ? (c'est une question lol)
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 21 sept. 2006 à 13:36
ravi que ca plaise...
Il s'agissait, dans le cas de la demande du Forum, de mémoriser le Login/Pass... et de ne pas lui demander de montrer patte blanche a chaque instanciation du programme
CADRATURE
Messages postés25Date d'inscriptionmercredi 26 novembre 2003StatutMembreDernière intervention13 juin 2009 21 sept. 2006 à 13:25
Super
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 20 sept. 2006 à 18:41
"mais ca évite API, registre et fichier"
Le principe de SaveSettings et GetSettings est justement d'écrire dans le registre...
@+
Mayzz
Messages postés2813Date d'inscriptionmardi 15 avril 2003StatutMembreDernière intervention 2 juin 202028 20 sept. 2006 à 18:39
Il y a aussi sous VB les fonctions SaveSetting et GetSetting pour ceux qui ne connaissent pas mais le principe est tout autre et l'on ne peut accèder à la configuration que par le proramme l'ayant enregistrer(pas de partage) mais ca évite API, registre et fichier, sinon bravo pour ce code ! Je trouve ca très utile.
cs_Warning
Messages postés516Date d'inscriptionsamedi 3 février 2001StatutMembreDernière intervention24 octobre 20062 20 sept. 2006 à 13:33
Un seul mot: Super ! Et aussi super bonne idée.
cs_eldim
Messages postés956Date d'inscriptionlundi 30 mai 2005StatutMembreDernière intervention21 août 20141 20 sept. 2006 à 08:21
Bonjour,
C'est vraiment génial ce truc là !!!
Bravo
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 19 sept. 2006 à 13:39
Salut, je tombe sur cette source un peu par hasard (squattage du centre IF à midi, et titre de la source qui m'a attiré) et je n'ai pas pu encore tester (cause of Linux), mais çà semble vraiment intéressant.
Il est clair que c'est beaucoup mieux que de créer un *.txt... ;)
@+
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 19 sept. 2006 à 12:55
Ah ouais c'est pas mal ça, je me suis toujours demandé comment faire
Par contre tu devrais peut etre appeler la source "partage de variables..." ça serait peut etre plus clair, car la j'avais aucune idée du code sur lequel j'allait tomber quand j'ai cliqué dessus (enfin j'ai vu renfield, j'ai pas hésité ^^)
++
bouv
Messages postés1411Date d'inscriptionmercredi 6 août 2003StatutMembreDernière intervention 3 mars 20191 19 sept. 2006 à 08:49
24 août 2012 à 13:42
24 août 2012 à 13:22
Merci
24 août 2012 à 13:20
24 août 2012 à 13:12
24 août 2012 à 10:18
Attention quand même à ne pas saturer la mémoire vive au risque d'avoir quelques ralentissements :-)
Pour la grande quantité de données de quoi s'agit-il ?
Le code n'a pas été prévu pour ça : variable Stream de type String.
Il faudra aussi revoir la variable MAPSIZE (16 Ko par défaut).
Avec un peu d'effort cela doit être possible.
PRADIER4>>FireEvent permet de SubClasser la variable. En gros ton appli est avertit dès que la variable est modifiée. Donc nul besoin de timer.
24 août 2012 à 09:41
Sinon, encore merci ce code m'a été très utile.
23 août 2012 à 19:51
Par ailleurs, y a til un moyen de savoir si un autre logiciel est présent sur cette zone mémoire? Avec un code envoyé tous les 1/1000 secondes par un timer et quand ya plus c qu'il est plus là?
9 févr. 2012 à 18:39
si souci, me contacter (faudra peut etre simplifier en retirant le cryptage, par exemple)
9 févr. 2012 à 16:14
29 mars 2011 à 20:06
Public Sub New(ByVal Nom As NomPredefini)
Dim NomFichier As String = Nom.ToString
meMsgStreamChanged = RegisterWindowMessage("InterProcess_StreamChanged" & Nom)
'meMsgCustomEvent = RegisterWindowMessage("InterProcess_CustomEvent")
'mhMap = OpenFileMapping(FILE_MAP_READ Or FILE_MAP_WRITE, 0, MAPKEY)
mhMap = OpenFileMapping(FILE_MAP_READ Or FILE_MAP_WRITE, 0, NomFichier)
Dim tp As CreateParams = New CreateParams()
tp.ClassName = "STATIC"
CreateHandle(tp)
If mhMap = 0 Then
' mhMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, MAPSIZE, MAPKEY)
mhMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, MAPSIZE, NomFichier)
If mhMap <> 0 Then
Dim pMem As IntPtr = MapViewOfFile(mhMap, FILE_MAP_WRITE, 0, 0, 0)
If pMem <> IntPtr.Zero Then
ZeroMemory(pMem, MAPSIZE)
UnmapViewOfFile(pMem)
End If
End If
End If
End Sub
NomPredefini du constructeur est un enum pour nommer mes trois "tuyaux".
29 mars 2011 à 15:50
Je déterre un peu ce code en espérant qu'on me réponde.
Voila, j'ai trois applis (indépendantes) en VB.NET avec des base de données qui contiennent des données proches et/ou complémentaires. J'ai créé une quatrième appli qui contient une autre bdd avec juste les mappages des trois autres bases ainsi que plusieurs fenêtres.
J'utilise cette source légèrement modifié afin d'avoir trois noms différents de fichier virtuel et trois objet IP dans la quatrième appli.
Appli_1
|
|tuyau_1
|
Appli_4
/ \
tuyau_2/ \tuyau_3
/ \
Appli_2 Appli_3
Chaque "tuyau" est bien isolé, mais le problème est que les évènements StreamChanged qui se mélangent dans la quatrième appli. Par exemple, si du texte est envoyé de l'appli_1 vers l'appli_4, c'est le tuyau_3 qui déclenche l'évènement StreamChanged dans l'appli_4 (dernier tuyau créé ?) mais le stream du tuyau_3 est vide.
Si quelqu'un peut m'aider...
28 déc. 2009 à 22:16
du coup, ca allait pour partager des variables, mais le temps reel en patissait...
bon diagnostic et bonne resolution, une fois encore
28 déc. 2009 à 18:20
ex
Résultat inattendu !
Un simple doevents placé après le Postmessage HWND_BROADCAST résoud le problème. 8)
Bonnes fêtes de fin d'année.
17 déc. 2009 à 13:26
Je me permet de relancer concernant ma question sur le OpenFileMapping
Merci d'avance
++
17 déc. 2009 à 12:33
le nombre de téléchargement est tout de même la preuve que ta source ne laisse pas indifférent. 8)
17 déc. 2009 à 12:26
17 déc. 2009 à 12:19
je repiques l'idée et mets a jour rapidement
17 déc. 2009 à 12:16
Je vais regretter de t'avoir mis un 10 lol
Quid quand la valeur insérée est une chaine vide ?
J'ai contourné en remplaçant vbNullChar & vbNullChar par Chr(0) & Chr(255).
14 déc. 2009 à 15:05
Lors de la consultation d'une archive, aujourd'hui je dois :
- extraire le stream de la BDD
- le placer dans un fichier temporaire
- ouvrir le fichier
- surveiller sa fermeture
- supprimer le fichier du disque
Cette opération me ferait gagner un temps précieux en économisant les accès disque.
14 déc. 2009 à 14:45
si tu as un vrai fichier, pourquoi vouloir ouvrir son filemapping ?
14 déc. 2009 à 12:26
C'est superbe Renfield - que du bonheur dans cette source,
qui en plus est distribuée sous VB6 et VB.net.
8 déc. 2009 à 17:15
J'ai une question qui peut paraître absurde mais je la pose quand même.
Admettons que je place le Stream d'un vrai fichier dans le FileMapping (celui d'un pdf par exemple).
Peut-on ensuite appeler un substitut de la fonction FileOpen sur ce FileMapping pour l'ouvrir dans le prog par défaut ?
4 déc. 2009 à 19:01
4 déc. 2009 à 16:40
comme ça, on communique plus efficacement entre processus ^^
4 déc. 2009 à 16:36
++
4 déc. 2009 à 16:21
mais le subclassing avec NativeWindow est un vrai régal !
4 déc. 2009 à 16:16
++
4 déc. 2009 à 14:42
j'y ai inclus une version .Net certes allégée, mais plus simple a comprendre.
ici, on partage un bête flux texte (16Ko)
on a un evenement StreamChanged
pour le jeu du Dictionary fait en VB6, libre à vous de jouer a (dé)serialiser ce que vous voulez, comme vous le voulez ^^
3 déc. 2009 à 15:23
2 déc. 2009 à 23:57
2 juil. 2008 à 15:20
mais ca fonctionne...
Imports System.Runtime.InteropServices
Public Class SharedValues
' Pour que plusieurs programmes puissent échanger ces valeurs, il suffit de modifier la clé ci dessous :
Private Const MAPKEY As String = "SharedValues"
' Taille du tampon (8 Ko)
Private Const MAPSIZE = &H2000&
Private Const SECTION_MAP_READ As Integer = &H4
Private Const SECTION_MAP_WRITE As Integer = &H2
Private Const FILE_MAP_READ As Integer = SECTION_MAP_READ
Private Const FILE_MAP_WRITE As Integer = SECTION_MAP_WRITE
Private Const INVALID_HANDLE_VALUE As Integer = &HFFFFFFFF
Private Const PAGE_READWRITE As Integer = &H4
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Integer) As Integer
Private Declare Function CreateFileMapping Lib "kernel32.dll" Alias "CreateFileMappingA" (ByVal hFile As Integer, ByVal lpFileMappingAttributes As Integer, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer
Private Declare Function MapViewOfFile Lib "kernel32.dll" (ByVal hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As Integer
Private Declare Function OpenFileMapping Lib "kernel32.dll" Alias "OpenFileMappingA" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal lpName As String) As Integer
Private Declare Function UnmapViewOfFile Lib "kernel32.dll" (ByRef lpBaseAddress As IntPtr) As Integer
Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" (ByVal Destination As IntPtr, ByVal Length As Integer)
Private mhMap As Integer
Private msName As String
Private mnSize As Integer
Public ReadOnly Property Name() As String
Get
Name = msName
End Get
End Property
Public ReadOnly Property Size() As Integer
Get
Size = mnSize
End Get
End Property
Public Sub New()
Load(MAPKEY, MAPSIZE)
End Sub
Public Sub New(ByRef vsName As String)
Load(vsName, MAPSIZE)
End Sub
Public Sub New(ByVal vnSize As Integer)
Load(MAPKEY, vnSize)
End Sub
' Cette méthode permet de changer de mappage, ou de changer la taille de celui-ci...
Public Sub New(ByRef vsName As String, ByVal vnSize As Integer)
Load(vsName, vnSize)
End Sub
Private Sub Load(ByRef vsName As String, ByVal vnSize As Integer)
Dim pMem As IntPtr
' Si un mappage est ouvert, on le ferme...
If mhMap Then
CloseHandle(mhMap)
End If
' On enregistre le nom du mappage
msName = vsName
' Et on tente d'ouvrir le mappage
mhMap = OpenFileMapping(FILE_MAP_READ Or FILE_MAP_WRITE, 0, msName)
If mhMap = 0 Then
' Le mappage n'existe pas ?
' Nous allons donc le créer. Il aura la taille demandée par l'utilisateur.
mnSize = vnSize
' Création du mappage
mhMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, mnSize, msName)
If mhMap Then
' Le premier Integer dans le fichier sera la taille du mappage.
' Tout le reste est remplit par des 0
pMem = MapViewOfFile(mhMap, FILE_MAP_WRITE, 0, 0, 0)
If pMem Then
Marshal.WriteInt32(pMem, 0, mnSize)
ZeroMemory(New IntPtr(pMem.ToInt32 + 4), mnSize - 4)
UnmapViewOfFile(pMem)
End If
End If
Else
' Le mappage existe déjà. Nous lisons la taille de celui-ci
pMem = MapViewOfFile(mhMap, FILE_MAP_READ, 0, 0, 0)
If pMem Then
mnSize = Marshal.ReadInt32(pMem, 0)
UnmapViewOfFile(pMem)
End If
End If
End Sub
Public Sub Unload()
' Fermeture du mappage
If mhMap Then
CloseHandle(mhMap)
mhMap = 0
End If
End Sub
' Permet de récupérer une valeur en particulier du Stream.
Public Property Value(ByVal vsName As String) As String
Get
Value = vbNullString
Try
For Each sPair As String In Stream.Split(vbNullChar)
If sPair.StartsWith(vsName & "=") Then
Value = sPair.Substring(vsName.Length + 1)
Exit For
End If
Next sPair
Catch e As NullReferenceException
End Try
End Get
Set(ByVal value As String)
Try
Dim xsParts() As String = Stream.Split(vbNullChar)
For i As Integer = 0 To xsParts.GetUpperBound(0)
If xsParts(i).StartsWith(vsName & "=") Then
' Sinon, on modifie l'élement de notre tableau
xsParts(i) = vsName & "=" & value
' Et on reconstruit le Stream
Stream = Join(xsParts, vbNullChar)
Exit Property
End If
Next i
Stream = Join(xsParts, vbNullChar) & vbNullChar & vsName & "=" & value
Catch e As NullReferenceException
Stream = vsName & "=" & value
End Try
End Set
End Property
' Permet de récupérer le Stream enregistré dans le mapping
Public Property Stream() As String
Get
Dim pMem As IntPtr
Stream = vbNullString
pMem = MapViewOfFile(mhMap, FILE_MAP_READ, 0, 0, 0)
If pMem Then
' On récupère la taille effective des données
Dim nLength As Integer = Marshal.ReadInt32(pMem, 4)
If nLength > 0 Then
Dim xbData As Char() = New String(" ", nLength).ToCharArray
Marshal.Copy(New IntPtr(pMem.ToInt32 + 8), xbData, 0, nLength)
Stream = New String(xbData, 0, nLength)
End If
UnmapViewOfFile(pMem)
End If
End Get
Set(ByVal value As String)
Dim pMem As IntPtr
pMem = MapViewOfFile(mhMap, FILE_MAP_WRITE, 0, 0, 0)
If pMem Then
Dim xbData As Char() = value.ToCharArray
' On regarde si le mapping est assez grand pour contenir les données
If xbData.Length < mnSize Then
' Tous les autres bits sont remis à 0
ZeroMemory(New IntPtr(pMem.ToInt32 + 8 + xbData.Length), mnSize - 8 - xbData.Length)
' On ajoute la taille des données en début de mapping (après la taille du mapping)
Marshal.WriteInt32(pMem, 4, xbData.Length)
' Et, s'il y a des données, on les ajoutes dans le mapping
If xbData.Length > 0 Then
Marshal.Copy(xbData, 0, New IntPtr(pMem.ToInt32 + 8), xbData.Length)
End If
End If
UnmapViewOfFile(pMem)
End If
End Set
End Property
End Class
22 sept. 2006 à 23:04
Public Property Get Stream() As String
Public Property Let Stream(ByRef Value As String)
22 sept. 2006 à 19:16
22 sept. 2006 à 14:58
Dans Get Stream, si je met un point d'arret sur
CopyMemory ByVal sBuffer, ByVal pMem + 8, nLength
Je me rend compte que le Buffer est quasiment enregistré en clair. Ou du moins on peut distinguer mon Login et mon Password.
22 sept. 2006 à 13:14
@+
22 sept. 2006 à 12:03
je voulais dire en fait que ça évite de taper les API pour accéder au registre. c'est juste des fonctions incluses dans vb ça évite de taper trop de code =) Dsl je me suis mal exprimé
22 sept. 2006 à 10:43
si toutes les instances de la classe ShareValues sont coupées, on perds les infos...
vous pouvez sauvegarder le Stream, et de le restaurer a votre guise
22 sept. 2006 à 10:36
Avec savesetting les clés et valeurs sont retrouvées même après le redémarage du PC.
Le file mapping est-il physique?
22 sept. 2006 à 03:54
en utilisant la méthode Load....
reste que quelque soit son nom, en espionnant le logiciel, les APIs utilisées, etc, on pourras toujours trouver que le logiciel ouvre un File mapping (et même en obtenir le contenu).
comme le précise bouv, en ajoutant un Password (par le biai de la propriété du même nom), les données sont cryptées dans le file Mapping.
sans ce Password lors de la lecture...
21 sept. 2006 à 23:32
21 sept. 2006 à 20:57
Private Const MAPKEY As String = "MonLogiciel"
Seul celui qui cherche avec la valeur 'MonLogiciel' pourra lire ces données.
MADM@TT>>Renfield à dernièrement ajouté une fonction de cryptage des données pour mieux sécuriser le procédé.
21 sept. 2006 à 20:42
'# Pour que plusieurs programmes puissent échanger ces valeurs, il suffit de modifier la clé ci dessous :
Private Const MAPKEY As String = "SharedValues"
Peux-tu être plus clair sur ton commentaire ci-dessus.
21 sept. 2006 à 19:07
car soit y'a moyen de récupérer le mot de passe et le login,soit il s'agit d'une variable boolean genre true : loggé, false : pas loggé, mais dans ce cas y'a surement aussi moyen de récupérer sa valeur et de la modifier ? (c'est une question lol)
21 sept. 2006 à 13:36
Il s'agissait, dans le cas de la demande du Forum, de mémoriser le Login/Pass... et de ne pas lui demander de montrer patte blanche a chaque instanciation du programme
21 sept. 2006 à 13:25
20 sept. 2006 à 18:41
Le principe de SaveSettings et GetSettings est justement d'écrire dans le registre...
@+
20 sept. 2006 à 18:39
20 sept. 2006 à 13:33
20 sept. 2006 à 08:21
C'est vraiment génial ce truc là !!!
Bravo
19 sept. 2006 à 13:39
Il est clair que c'est beaucoup mieux que de créer un *.txt... ;)
@+
19 sept. 2006 à 12:55
Par contre tu devrais peut etre appeler la source "partage de variables..." ça serait peut etre plus clair, car la j'avais aucune idée du code sur lequel j'allait tomber quand j'ai cliqué dessus (enfin j'ai vu renfield, j'ai pas hésité ^^)
++
19 sept. 2006 à 08:49
Merci