A set of .NET Framework managed libraries for developing graphical user interfaces.
It sounds to me like you want to create shared memory. You can use memory-mapped-files to accomplish this.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
WHAT I HAVE:
Visual Basic 2019, WinForms, .NET Framework 4.6-4.8
MY ISSUE:
I want to structure a desktop app so that it can share specific information with related desktop apps--or with other instances of itself--when they're running at the same time. Each app or app instance would have its own instance of an object of some type, say MyClass,--which the relate apps or other app instances could look at to compare with their own corresponding MyClass instances.
For instance, an application that can be multiply-instanced might want to have, say, a file-name String that other instances of itself could see, so that the app can make sure that simultaneously-running instances aren't using and modifying the same file, the same document, the same picture, the same database, or the same whatever at the same time. Ideally, the ability to share and compare info should be a simple object-oriented thing that doesn't require me to explicitly set up a common file or common database simply for a relatively small amount of "state-info" for each app or app instance. (That seems like overkill!)
Give me some advice ASAP, please provide any code in VB.NET, and keep it as simple as possible, as I don't want to devote a large part of app development simply for the sharing and comparing of a relatively limited bit of data between a program and other programs or instances of itself.
A set of .NET Framework managed libraries for developing graphical user interfaces.
An object-oriented programming language developed by Microsoft that can be used in .NET.
It sounds to me like you want to create shared memory. You can use memory-mapped-files to accomplish this.
A small test with the simplest method, WM_COPYDATA
between 3 instances of the program, to be improved... :
Imports System.Runtime.InteropServices
Public Class Form1
Public Const WM_COPYDATA As Integer = &H4A
<StructLayout(LayoutKind.Sequential)>
Public Structure COPYDATASTRUCT
Public dwData As IntPtr
Public cbData As Integer
Public lpData As IntPtr
End Structure
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As COPYDATASTRUCT) As Integer
End Function
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure DATASTRUCT
Public hWnd As IntPtr
Public nPID As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=512)>
Public sMessage As String
End Structure
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sProcessName As String = System.AppDomain.CurrentDomain.FriendlyName
Dim nWindows As Integer = 0
Dim procs As Process() = Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(sProcessName))
If procs.Length > 0 Then
For Each proc As Process In procs
If (proc.MainWindowHandle <> IntPtr.Zero And proc.MainWindowHandle <> Me.Handle) Then
nWindows += 1
Dim data As DATASTRUCT
data.hWnd = proc.MainWindowHandle
data.nPID = proc.Id
data.sMessage = "This is a test"
Dim nSize As Integer = Marshal.SizeOf(data)
Dim pData As IntPtr = Marshal.AllocHGlobal(nSize)
Marshal.StructureToPtr(data, pData, True)
Dim cds As New COPYDATASTRUCT()
cds.cbData = nSize
cds.lpData = pData
Dim nRet As Integer = SendMessage(proc.MainWindowHandle, WM_COPYDATA, CInt(Me.Handle), cds)
If (nRet <> 1) Then
MessageBox.Show(String.Format("Error sending WM_COPYDATA) : 0x{0:X}", nRet), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Marshal.FreeHGlobal(pData)
End If
Next
End If
If (nWindows > 0) Then
MessageBox.Show(String.Format("WM_COPYDATA sent to {0} windows", nWindows.ToString()), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("WM_COPYDATA not sent", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
Friend WithEvents Button1 As Button
Friend WithEvents RichTextBox1 As RichTextBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Button1 = New System.Windows.Forms.Button()
Me.Button1.Location = New System.Drawing.Point(120, 16)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(80, 30)
Me.Button1.Text = "Button1"
Me.Button1.UseVisualStyleBackColor = True
Me.RichTextBox1 = New System.Windows.Forms.RichTextBox()
Me.RichTextBox1.Location = New System.Drawing.Point(60, 60)
Me.RichTextBox1.Name = "RichTextBox1"
Me.RichTextBox1.Size = New System.Drawing.Size(200, 120)
Me.RichTextBox1.Text = ""
Me.ClientSize = New System.Drawing.Size(320, 200)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.RichTextBox1)
CenterToScreen()
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If (m.Msg = WM_COPYDATA) Then
Dim pCDS As COPYDATASTRUCT = CType(m.GetLParam(GetType(COPYDATASTRUCT)), COPYDATASTRUCT)
If (pCDS.cbData = Marshal.SizeOf(GetType(DATASTRUCT))) Then
Dim data As DATASTRUCT = CType(Marshal.PtrToStructure(pCDS.lpData, GetType(DATASTRUCT)), DATASTRUCT)
Dim hWndFrom As IntPtr = data.hWnd
Dim nPIDFrom As Integer = data.nPID
Dim sMessage As String = data.sMessage
Dim sText = String.Format("From window : 0x{0:X} (PID={1}){2}Message : {3}{2}", hWndFrom, nPIDFrom.ToString(), Environment.NewLine, sMessage)
RichTextBox1.Text += sText
m.Result = CType(1, IntPtr)
Return
End If
End If
MyBase.WndProc(m)
End Sub
End Class
You can type on Google :
Interprocess Communication .net
and you will find samples using the various IPC methods, like :
VB.NET IPC InterProcess Communication
Simple Inter-Process Communication In VB.Net
How to: Use Anonymous Pipes for Local Interprocess Communication
etc...
The examples seem (moreorless) straightforward. The problem is, they're all 1-way communication between 2 distinct processes--1 a server, the other a client. What if I need the communication to be 2-way? Moreover, what if--as I previously talked about--the processes are alternate instances of a single program? In either case, an app would have to be able to be server AND client (simultaneously or alternately). I need a better example set.
You apparently didn't carefully read the full description of my issue. I'm not talking about sharing data within a single run-time instance of a single project or a single solution. I'm talking about a situation where 2 or more apps' .exe's are executing simultaneously, or where 2 or more instances of a single app's .exe are executing simultaneously.
This is principally about Windows' multitasking nature, and finding a way to allow different programs, or different instances of a single program, to (economically) communicate info with each other when they're running at the same time. I want to overcome the tendency of programs or program instances that are executing "in parallel" to act like fully separate islands with respect to each other. If program X and program Y--which are not necessarily in the same solution--are active in Windows simultaneously, then what's the most convenient way for X and Y to share and compare some of each other's info? Also, if multiple "run-time 'copies'"--instance--of program X are active at the same time, how does one instance of X share and compare info with the other instances of X (arguably a more problematic concern)?
Does this explain my situation better?