שתף באמצעות


Best way to communicate between two windows applications in vb.net

Question

Thursday, December 7, 2017 11:57 AM

Hi All,

I have two windows application (2 different .exe), lets assume app1 and app2.

app1 starts app2 using System.Diagnostics.Process.Start().

app2 takes some time to load completely. Now i want to inform app1 only after app2 loads completely.

How to send this information (which could be a boolean value) from app2 to app1?

Thanks in Advance.

All replies (7)

Thursday, December 7, 2017 6:34 PM ✅Answered

 Since you have access to modify the code of the 2nd application and you are starting it using the Process class,  you can simply redirect the standard output of the Process when you start it.  Then you can read the StandardOutputStream asynchronously or synchronously until your 2nd application has finished loading and it writes a special message back to the first application through the StandardOutputStream.

 You can test this with two new testing windows form applications as shown below.

 This first code block below is the code for the 2nd application,  the one that gets started using the Process class from the first application.

Public Class Form1 'this is the main form of the the 2nd application

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        Threading.Thread.Sleep(2000) 'just to simulate the form being busy doing something for a few seconds
        Console.WriteLine("FinishedLoading") 'write your special message to the StandardOutputStream to indicate this application has finished loading or doing something
    End Sub

End Class

 

 Here are two examples of the code that can be used in the first application for starting the 2nd application Process and monitoring the redirected StandardOutputStream for the special message to be written to it from the 2nd application.

 This first example reads the StandardOutputStream asynchronously via the OutputDataReceived event of the Process,  meaning it will start the process and continue executing other code until the special message is received in the OutputDataReceived event.

Public Class Form1 'this is the form of the first application
    Private WithEvents Proc As Process = Nothing

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If Proc Is Nothing OrElse Proc.HasExited Then
            Proc = New Process
            Proc.EnableRaisingEvents = True
            With Proc.StartInfo
                .FileName = "C:\TestFolder\MyOtherApplication.exe"
                .UseShellExecute = False
                .RedirectStandardOutput = True
            End With
            Proc.Start()
            Proc.BeginOutputReadLine()
        End If
    End Sub

    Private Sub Proc_OutputDataReceived(sender As Object, e As DataReceivedEventArgs) Handles Proc.OutputDataReceived
        If e.Data = "FinishedLoading" Then 'if the standard output stream receives your special message,  then do something...
            MessageBox.Show("My other app has finished loading...")
        End If
    End Sub
End Class

 

 This is the second example of how you can start the Process read the StandardOutputStream synchronously,  meaning that it will stop the main application from executing any further code until a message is received from the 2nd application.

Public Class Form1 'this is the form of the first application
    Private WithEvents Proc As Process = Nothing

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If Proc Is Nothing OrElse Proc.HasExited Then
            Proc = New Process
            With Proc.StartInfo
                .FileName = "C:\TestFolder\MyOtherApplication.exe"
                .UseShellExecute = False
                .RedirectStandardOutput = True
            End With
            Proc.Start()

            While Proc.StandardOutput.ReadLine <> "FinishedLoading" 'wait until the special message is written to the StandardOutputStream
                Threading.Thread.Sleep(100)
            End While

            MessageBox.Show("The Other Application Has Finished Loading...")
        End If
    End Sub
End Class

 

 

 

 PS - I should also mention that reading the StandardOutputStream asynchronously would allow the possibility of your 2nd application to send more messages or other text data back to the first application if needed.

If you say it can`t be done then i`ll try it


Thursday, December 7, 2017 12:11 PM

The following does a string but of course you can do a Boolean too.

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator


Thursday, December 7, 2017 12:27 PM

The following does a string but of course you can do a Boolean too.

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator

Hi Karen,

Thanks for replying.

For using this namedpipeserverstream i assume that we need to have server client relation between two applications.

In my case there is no such relation between application.


Thursday, December 7, 2017 12:52 PM

There are plenty of methods for IPC.

One of the simplest ones is using custom messages (WM_USER + x)

For example, you send WM_USER + 100 from app2,

and in app1 :

Public Const WM_USER As Integer = &H400

Protected Overrides Sub WndProc(ByRef m As Message)
    If (m.Msg = WM_USER + 100) Then
        ' Code
    Else
        MyBase.WndProc(m)
    End If
End Sub

Thursday, December 7, 2017 12:52 PM

In this simple scenario, consider the next approach too. The app1 will start app2, then wait using this code:

   Using ewh = New EventWaitHandle(False, EventResetMode.AutoReset, "MySpecialEvent1")

      ewh.Reset()

      Process.Start("app2.exe")

      ewh.WaitOne()

   End Using

 

The app2 will perform the initialisation, then execute this code:

   Using ewh = EventWaitHandle.OpenExisting("MySpecialEvent1")

      ewh.Set()

   End Using

 

It is possible to use WaitOne with time-out.


Thursday, December 7, 2017 1:09 PM

You assumes to much or don't tell us to few. 

With VB there can be made many kind of windows applications. 

However, it seems that you think there is only one taste as it was in the days of VB1.

Success
Cor


Thursday, December 7, 2017 1:09 PM

It's been around for a long time, but DDE is also an option. There is a component library for .NET:

http://www.fredshack.com/docs/dde.vb.net.html

Paul ~~~~ Microsoft MVP (Visual Basic)