Solved

Communicating between applications

Posted on 1998-11-20
3
197 Views
Last Modified: 2010-05-03
Hi all,

Here's my problem:
I need some form of communication between 2 different running VB programs. For example, I may run a method in Prog1 to send a message "Testing 123" to Prog2. And in Prog2, an event will probably be triggered, and the sent message can be read. The message passed between the two programs may be a string or even 2 or 3 strings.

How should I go about doing this? Please point me in the right direction.

Perhaps this behavior is appropriate to be made into a OCX. That is, the control will take care of the messaging, the 2 programs just need to add this control. If so, I believe the 'communication' part of the problem would still remain the same.

Maybe such a ocx already exists, but I would still like to know how to achieve this.

Thanks.
Minos
0
Comment
Question by:Minos111998
  • 2
3 Comments
 
LVL 14

Accepted Solution

by:
waty earned 100 total points
ID: 1445822
The first easy communications between application is files. I use it in my process. The reason that is : I could make run my process on the same computer or even on several other computer. The configuration is very easy. The programmation is very easy too. Just add a time and check for a flag file indicating that a command file is present.

Otherwise, there are several solutions. The one I propose you here is using mailslot. Here is the class :

' #VBIDEUtils#************************************************************
' * Programmer Name  : Waty Thierry
' * Web Site         : www.geocities.com/ResearchTriangle/6311/
' * E-Mail           : waty.thierry@usa.net
' * Date             : 17/11/98
' * Time             : 12:03
' * Module Name      : class_MailSlot
' * Module Filename  : MailSlot.cls
' **********************************************************************
' * Comments         :
' *
' *
' **********************************************************************

Option Explicit

Private Type SECURITY_ATTRIBUTES
   nLength                 As Long
   lpSecurityDescriptor    As Long
   bInheritHandle          As Long
End Type

Private Type OVERLAPPED
   Internal                As Long
   InternalHigh            As Long
   offset                  As Long
   OffsetHigh              As Long
   hEvent                  As Long
End Type

Private Declare Function CreateMailslot Lib "kernel32" Alias "CreateMailslotA" (ByVal lpName As String, ByVal nMaxMessageSize As Long, ByVal lReadTimeout As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As String, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As String) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As String) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As String) As Long
Private Declare Function GetMailslotInfo Lib "kernel32" (ByVal hMailslot As Long, ByVal lpMaxMessageSize As String, lpNextSize As Long, lpMessageCount As Long, ByVal lpReadTimeout As String) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function DuplicateHandle Lib "kernel32" (ByVal hSourceProcessHandle As Long, ByVal hSourceHandle As Long, ByVal hTargetProcessHandle As Long, lpTargetHandle As Long, ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwOptions As Long) As Long

Private Const INVALID_HANDLE_VALUE = -1
Private Const MAILSLOT_NO_MESSAGE = (-1)
Private Const MAILSLOT_WAIT_FOREVER = (-1)
Private Const GENERIC_WRITE = &H40000000
Private Const FILE_SHARE_READ = &H1
Private Const OPEN_EXISTING = 3
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const DUPLICATE_SAME_ACCESS = &H2

Private lHSlot As Long
Private sMailslotName As String
Private lCurrentProcess As Long

Private colMessages As New Collection

Public Function Create(SName As String)
   
   Dim sFileName              As String
   Dim sProcess               As String
   Dim sMailslotHandle        As String
   Dim lProcess               As Long
   Dim lMailslotHandle        As Long
   Dim nMailslotInfoFile      As Integer
   Dim lRet                   As Long
   Dim nLogFile               As Integer
   Dim lpSecurityAttributes   As SECURITY_ATTRIBUTES

   On Error GoTo Error_Create

   lpSecurityAttributes.nLength = Len(lpSecurityAttributes)
   lpSecurityAttributes.lpSecurityDescriptor = 0
   lpSecurityAttributes.bInheritHandle = True

   If lHSlot <> 0 And lHSlot <> INVALID_HANDLE_VALUE Then
      Dim iRet As Integer
      iRet = MsgBox("You are currently using a mailslot: " & sMailslotName & ".  Would you like to close that mailslot and create this one?", vbQuestion + vbYesNo)
      If iRet = vbNo Then Exit Function
      CloseHandle lHSlot
   End If

   sFileName = "C:\" & SName & ".MSF"
   nMailslotInfoFile = FreeFile

   sMailslotName = SName
   lHSlot = CreateMailslot("\\.\mailslot\" & sMailslotName, 0, MAILSLOT_WAIT_FOREVER, lpSecurityAttributes)
   If lHSlot = INVALID_HANDLE_VALUE Then
      'Check for an existing instance and duplicate that handle
      If Len(Dir$(sFileName, vbHidden)) Then
         'Open the file
         Open sFileName For Input Shared As #nMailslotInfoFile
         Line Input #nMailslotInfoFile, sProcess$
         Line Input #nMailslotInfoFile, sMailslotHandle$
         Close nMailslotInfoFile

         lProcess& = Val(sProcess$)
         lMailslotHandle& = Val(sMailslotHandle$)

         'Now duplicate the mailslot handle
         lRet = DuplicateHandle(lProcess&, lMailslotHandle&, lCurrentProcess&, lHSlot, 0, False, DUPLICATE_SAME_ACCESS)

         nLogFile = FreeFile
         Open "C:\MAILSLOT.LOG" For Output Shared As #nLogFile
         Print #nLogFile, "Old Process: " & CStr(lProcess&)
         Print #nLogFile, "Old Handle:  " & CStr(lMailslotHandle&)
         Print #nLogFile, "New Process: " & CStr(lCurrentProcess&)
         Print #nLogFile, "New Handle:  " & CStr(lHSlot&)
         Print #nLogFile, ""
         Close #nLogFile

         If lRet = 0 Then
            lHSlot = 0
            Create = 0
         Else
            Create = lHSlot
         End If
      Else
         Create = 0
      End If
   Else
      Create = lHSlot

      'If the mailslot info file existed, kill it
      If Len(Dir$(sFileName)) Then Kill sFileName

      'Now create the mailslot info file
      Open sFileName For Output Shared As #nMailslotInfoFile
      Print #nMailslotInfoFile, CStr(lCurrentProcess&)
      Print #nMailslotInfoFile, CStr(lHSlot)
      Close #nMailslotInfoFile

      Reset

      'Now make it hidden
      SetAttr sFileName, vbHidden
   End If

   Exit Function

Error_Create:
   Exit Function

End Function

Public Function MailWrite(sMessage As String) As Long
   
   On Error GoTo Error_MailWrite

   Dim nHFile           As Long
   Dim nBytesWritten    As Long
   Dim nResult          As Long
   Dim bytMessage()     As Byte

   If lHSlot = 0 Or lHSlot = INVALID_HANDLE_VALUE Then
      MailWrite = False
   Else
      nHFile = CreateFile("\\*\mailslot\" & sMailslotName$, GENERIC_WRITE, FILE_SHARE_READ, vbNullString, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, vbNullString)
      If nHFile = INVALID_HANDLE_VALUE Then
         MailWrite = False
         GoTo MailWriteExit
      End If

      ReDim bytMessage(1 To Len(sMessage) + 1)
      bytMessage = " " & sMessage & Chr$(0)
      nResult = WriteFile(nHFile, bytMessage(1), (Len(sMessage) * 2) + 1, nBytesWritten&, vbNullString)
      If nResult = 0 Then
         MailWrite = False
         GoTo MailWriteExit
      End If

      MailWrite = True
   End If

MailWriteExit:

   CloseHandle nHFile

   Exit Function

Error_MailWrite:
   Exit Function

End Function

Private Sub Class_Initialize()
   
   lHSlot = 0

End Sub

Private Sub Class_Terminate()
   
   On Error GoTo Error_Class_Terminate

   'Destroy the created mailslot (if any)
   If lHSlot Then
      CloseHandle lHSlot
   End If

   Exit Sub

Error_Class_Terminate:
   Exit Sub

End Sub

Public Function MailRead(Optional nMessageCount) As String
   
   On Error GoTo Error_MailRead
   
   Dim lpNextSize          As Long
   Dim lpMessageCount      As Long
   Dim lpBytesRead         As Long
   Dim bytMessage()        As Byte
   Dim lResult             As Long
   Dim sTemp               As String
   Dim i                   As Integer

   If lHSlot = 0 Or lHSlot = INVALID_HANDLE_VALUE Then
      If Not IsMissing(nMessageCount) Then nMessageCount = 0
      MailRead = ""
   Else
      lResult = GetMailslotInfo(lHSlot, vbNullString, lpNextSize&, lpMessageCount&, vbNullString)
      If lResult = 0 Then
         'MsgBox "Error retrieving mailslot messages.", vbExclamation
         'Stop
      End If

      If lpMessageCount& = 0 Then
         If Not IsMissing(nMessageCount) Then nMessageCount = 0
         MailRead = ""
      Else
         If Not IsMissing(nMessageCount) Then nMessageCount = lpMessageCount& - 1

         If lpNextSize& > 0 Then
            ReDim bytMessage(1 To (lpNextSize& * 2))
            bytMessage = Space$(lpNextSize& * 2)
            lResult = ReadFile(lHSlot, bytMessage(1), lpNextSize&, lpBytesRead&, vbNullString)
            MailRead = Trim(LeftB(bytMessage, lpBytesRead& + 1))
         Else
            MailRead = ""
            If Not IsMissing(nMessageCount) Then nMessageCount = 0
         End If
      End If
   End If

   Exit Function

Error_MailRead:
   Exit Function

End Function

Public Property Get ProcessHandle() As Long
   
   ProcessHandle = lCurrentProcess

End Property

Public Property Let ProcessHandle(ByVal lNewValue As Long)
   
   lCurrentProcess = lNewValue

End Property



0
 

Author Comment

by:Minos111998
ID: 1445823
Thanks waty for the reply. I think that's what I'm looking for. Either mailslots or pipes. Thanks for your code as well.

But I have another question. Since two applications are going to have this class and if I use this class directly, wouldn't that mean that each app will be only able to write to it's own mailslot and read from it. I need two mailslots because the information path should be bidirectional.

Would the solution be to modify the MailSlotName variable of the CreateFile in MailWrite? That would mean fixing the mailslot names of both applications.

Is that the way or is there some other way?

Thanks a lot in advance.

0
 
LVL 14

Expert Comment

by:waty
ID: 1445824
Yes, you have to use the same mailslotname in the both applications.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now