Hallo,
Du kannst so eine Verbindung z.B. über
TCP/IP-Sockets, oder über
NamedPipes realisieren.
Die NamedPipe ist meiner Meinung nach die bessere Variante, wenn Du das z.B. in Deinem Netzwerk nutzen willst.
Was Du jedenfalls immer benötigst ist ein Listener (Server), der auf Anfragen wartet und diese bearbeitet und ggf. eine Rückmeldung zur Anfrage sendet. Soll das in beide Richtungen laufen brauchst Du zwei Server.
Hier eine Klasse, mit der Du beides realisieren kannst. Musst nur die NamedPipes-Namen vergeben und in jeder Anwendung den Server Starten (und beim Beenden auch wieder schließen)
'----
'Bsp für den Aufruf
Private Co_NamedPipes_Messenger1 As New CU.CO.co_NamedPipes_Messenger
Co_NamedPipes_Messenger1.ConnectTo_ServerName = „.“
Co_NamedPipes_Messenger1.Encoding = Nothing
Co_NamedPipes_Messenger1.Pipename = „Z_B_DeinAnwendungsname“
Co_NamedPipes_Messenger1.TimeOut = 15
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Co_NamedPipes_Messenger1.Server_Start()
Co_NamedPipes_Messenger1.SendToApplication(„Test“, 0, DeineProcessID)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Co_NamedPipes_Messenger1.Server_Stop()
End Sub
'----
Imports System.ComponentModel
Imports System.Drawing
Namespace CU.CO
‚‘’
‚‘’ Über diese Komponente können Strings an alle laufenden Prozesse des eingestellten PC’s gesendet werden,
‚‘’ die ebenfalls diese Komponente implementieren und den selben Pipenamen verwenden.
‚‘’
‚‘’ Diese Komponente reagirt nicht auf selbst versendete Strings! _
Public Class co_NamedPipes_Messenger
Public Enum enum_MessageType
leer = 0
info = 10
suche_Kunden = 100
suche_Lieferanten = 101
suche_Artikel = 102
suche_Retouren = 103
suche_Rechnungen = 104
TabellenAktualisieren = 1000
DatensatzAktualisieren = 10000
RestartThisServer = 100000
End Enum
#Region „Deklaration“
Private m_Encoding As System.Text.UTF8Encoding
‚‘’
‚‘’ Haupt Pipe-Namen (Ohne ProzessID)
‚‘’
‚‘’
Private m_PipenamePrev As String = „“
‚‘’
‚‘’ Timeout für die Verbindung (Da alle laufenden Prozesse des Zielrechners durchlaufen werden sollte der Wert des Timeouts sehr gering gehalten werden!)
‚‘’
‚‘’
Private m_TimeOut As Integer = 15
‚‘’
‚‘’ Der eigentliche Server
‚‘’
‚‘’
Private m_PipeServer As System.IO.Pipes.NamedPipeServerStream = Nothing
‚‘’
‚‘’ Der absolute Pipenamen diesere Instanz (mit ProzessID)
‚‘’
‚‘’
Private m_PipenameKomplete As String = „“
‚‘’
‚‘’ Name des PC’s (Im Netzwerk), an den die Daten versendet werden sollen.
‚‘’ !Achtung! für den Lokalhost muss „.“ verwendet werden.
‚‘’
‚‘’
Private m_ConnectTo_ServerName As String = „“
‚‘’
‚‘’ Interne Variable die angibt, ob der Server gestartet wurde.
‚‘’
‚‘’
Private m_ServerActive As Boolean = False
#End Region
#Region „Propertys“
‚‘’
‚‘’ Diese Eigenschaft gibt an, ob der Server gestartet wurde.
‚‘’
‚‘’
‚‘’
‚‘’
Public ReadOnly Property ServerActive() As Boolean
Get
Return m_ServerActive
End Get
End Property
‚‘’
‚‘’ Timeout für die Verbindung (Da alle laufenden Prozesse des Zielrechners durchlaufen werden sollte der Wert des Timeouts sehr gering gehalten werden!)
‚‘’
‚‘’
‚‘’
‚‘’
Public Property TimeOut() As Integer
Get
Return m_TimeOut
End Get
Set(ByVal value1 As Integer)
m_TimeOut = value1
End Set
End Property
‚‘’
‚‘’ Der Pipenamen diesere Instanz (Ohne ProzessID)
‚‘’ !Achtung! dieser Wert nimmt nur Einfluss wenn anschließend die Funktion Server_Start() ausgeführt wird.
‚‘’ Sollte der Server bereits laufen muss dieser zuvor beendet werden (Server_Stop()) und anschließend neu gestartet werden.
‚‘’
‚‘’
‚‘’
‚‘’
Public Property Pipename() As String
Get
Return m_PipenamePrev
End Get
Set(ByVal value1 As String)
m_PipenamePrev = value1
End Set
End Property
‚‘’
‚‘’ Gibt die Encodierung der Daten an.
‚‘’
‚‘’
‚‘’
‚‘’
Public Property Encoding() As System.Text.Encoding
Get
Return m_Encoding
End Get
Set(ByVal value1 As System.Text.Encoding)
m_Encoding = value1
End Set
End Property
‚‘’
‚‘’ Name des PC’s (Im Netzwerk), an den die Daten versendet werden sollen.
‚‘’ !Achtung! für den Lokalhost muss „.“ verwendet werden.
‚‘’
‚‘’
‚‘’
‚‘’
Public Property ConnectTo_ServerName() As String
Get
Return m_ConnectTo_ServerName
End Get
Set(ByVal value1 As String)
If value1 = „“ Then
'Localhost
m_ConnectTo_ServerName = „.“
Else
m_ConnectTo_ServerName = value1
End If
End Set
End Property
#End Region
#Region „Events“
‚‘’
‚‘’ Dieses Event wird bei jeder Statusänderung ausgeführt.
‚‘’
‚‘’ Stellt die laufende Instanz dar.
‚‘’ Stellt die Nachricht / Status dar.
‚‘’ Zeitpunkt des Ereignisses.
‚‘’
Public Event cu_StatusMessage(ByVal sender As Object, ByVal msg As String, ByVal Time As Date)
‚‘’
‚‘’ Dieses Event wird ausgelöst wenn eine neue Nachricht von einem anderen Prozess eingeht.
‚‘’
‚‘’ Stellt die laufende Instanz dar.
‚‘’ Stellt die ProzessID des Prozesses dar, welcher die Nachricht versendet hat.
‚‘’ Stellt die Nachricht dar.
‚‘’ Zeitpunkt des Ereignisses.
‚‘’
Public Event cu_MessageRecieved(ByVal sender As Object, ByVal SendingProcessID As Integer, ByVal MessageType As enum_MessageType, ByVal msg As String, ByVal Time As Date)
‚‘’
‚‘’ Dieses Event wird ausgelöst wenn eine Nachricht versendet wurde.
‚‘’
‚‘’ Stellt die laufende Instanz dar.
‚‘’ Stellt die ProzessID des Prozesses dar, an welchen die Nachricht versendet wurde.
‚‘’ Stellt die Nachricht dar, die versendet wurde.
‚‘’ Zeitpunkt des Ereignisses.
‚‘’
Public Event cu_MessageSended(ByVal sender As Object, ByVal SendingProcessID As Integer, ByVal MessageType As enum_MessageType, ByVal msg As String, ByVal Time As Date)
‚‘’
‚‘’ Wird bei jedem auftretenden Fehler ausgelöst (Außer bei Timeout).
‚‘’
‚‘’ Stellt die laufende Instanz dar.
‚‘’ Die Fehlerbeschreibung
‚‘’ Zeitpunkt des Ereignisses.
‚‘’
Public Event cu_Error(ByVal sender As Object, ByVal curError As System.Exception, ByVal Time As Date)
#End Region
#Region „Funktionen“
‚‘’
‚‘’ Tritt ein, wenn eine Nachricht eingeht.
‚‘’
‚‘’
‚‘’
Private Sub SubOrFunc_ConnectionCallback(ByVal ar As IAsyncResult)
Try
''SubOrFunc_UpdateStatus(„ConnectionCallback() fired.“)
m_PipeServer.EndWaitForConnection(ar)
''SubOrFunc_UpdateStatus(„End Waiting for Connection.“)
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(m_PipeServer)
Dim strProcID As String = sr.ReadLine()
Dim str_MessageType As enum_MessageType = CInt(sr.ReadLine())
Dim strMessage As String = sr.ReadLine()
''SubOrFunc_UpdateStatus(„Received ProcID String (“ & strProcID & "), string length = " & strProcID.Length.ToString)
''SubOrFunc_UpdateStatus(„Received Message String (“ & strMessage & "), string length = " & strMessage.Length.ToString)
’ Me.tbxConversation.Text &= " Data recevied: " & DateTime.Now.ToLongTimeString() & ": " & strProcID & " " & strMessage & vbCrLf
RaiseEvent cu_MessageRecieved(Me, strProcID, str_MessageType, strMessage & Environment.NewLine, Now)
System.Windows.Forms.Application.DoEvents()
''SubOrFunc_UpdateStatus(„Disconnecting connection.“)
m_PipeServer.Disconnect()
If str_MessageType = enum_MessageType.RestartThisServer Then
Dim proc As Process = Process.GetCurrentProcess()
'Nur wenn Sender auch dieser Server ist!
If proc.Id = strProcID Then
System.Windows.Forms.Application.DoEvents()
m_PipeServer.Close()
m_ServerActive = False
End If
Else
m_PipeServer.BeginWaitForConnection(AddressOf SubOrFunc_ConnectionCallback, Nothing)
''SubOrFunc_UpdateStatus(„Waiting for connection.“)
End If
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
End Sub
’ Dim m_IAsyncResult As IAsyncResult
‚‘’
‚‘’ Über diese Funktion wird der Server gestartet.
‚‘’ !Achtung! Alle Propertys sollten vor dem Aufruf dieser Funktion angepasst sein!
‚‘’
‚‘’
Public Sub Server_Start()
Try
If m_ServerActive = False Then
m_PipenameKomplete = m_PipenamePrev & Process.GetCurrentProcess.Id
''SubOrFunc_UpdateStatus("Creating Named Pipe Server: " & m_PipenameKomplete)
m_PipeServer = New System.IO.Pipes.NamedPipeServerStream(m_PipenameKomplete, System.IO.Pipes.PipeDirection.In, 1, System.IO.Pipes.PipeTransmissionMode.Message, System.IO.Pipes.PipeOptions.Asynchronous)
''SubOrFunc_UpdateStatus(„Named Pipe Created.“)
m_PipeServer.BeginWaitForConnection(AddressOf SubOrFunc_ConnectionCallback, Nothing)
''SubOrFunc_UpdateStatus(„Waiting for connection.“)
m_ServerActive = True
End If
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
End Sub
‚‘’
‚‘’ Stoppt den Server
‚‘’
‚‘’
Public Sub Server_Stop()
Try
If m_ServerActive = True Then
SendAbort()
End If
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
End Sub
‚‘’
‚‘’ Verwenden Sie diese Funktion um eine Nachricht an einen bestimmten Prozesse zu senden!
‚‘’
‚‘’ String der gesendet wird. !Achtung! es wird immer ein Zeilenumbruch angehängt!
‚‘’ Die Prozessid der Application, an die die Nachricht gesendet werden soll.
‚‘’ Gibt einen String zurück, in dem alle Server aufgeführt werden, die die Nachricht erhalten haben.
‚‘’
Public Function SendToApplication(ByVal Msg As String, ByVal MessageType As enum_MessageType, ByVal curProcessID As String) As String
Dim i_ReturnValue As String = „“
Try
Dim i_MSG As String = Msg
If Not String.IsNullOrEmpty(i_MSG) Then
If i_MSG.Substring(i_MSG.Length - 2) = Environment.NewLine Then
i_MSG = i_MSG.Substring(0, i_MSG.Length - 2)
End If
'Dim proc As Process = Process.GetCurrentProcess()
‚‘ Dim strTrgProcessName = proc.ProcessName
‚‘ If Me.cbxOtherInstanceInDebugger.Checked Then strTrgProcessName &= „.vshost“
‚‘ Dim processes() As Process = Process.GetProcessesByName(strTrgProcessName)
'Dim processes() As Process = Process.GetProcesses
'If processes.Length > 0 Then
Dim bytesMessage() As Byte = System.Text.Encoding.Default.GetBytes(i_MSG & Environment.NewLine)
Dim bytesProcID() As Byte = System.Text.Encoding.Default.GetBytes(curProcessID & vbCrLf)
Dim bytesMessageType() As Byte = System.Text.Encoding.Default.GetBytes(MessageType & vbCrLf)
’ For Each p As Process In processes
’ If p.Id proc.Id Or Msg = „ClosePipeNameServer“ Then ’ don’t send to self
’ Dim strServerPipeName As String = p.ProcessName & „_“ & p.Id
Dim strServerPipeName As String = m_PipenamePrev & curProcessID
''SubOrFunc_UpdateStatus(„Attempting to connect to server " & strServerPipeName & „. Timeout = " & m_TimeOut.ToString & " milliseconds.“)
Dim pipeStream As System.IO.Pipes.NamedPipeClientStream = New System.IO.Pipes.NamedPipeClientStream(“.", strServerPipeName, System.IO.Pipes.PipeDirection.Out) ’ „.“=localhost
Try
pipeStream.Connect(m_TimeOut)
''SubOrFunc_UpdateStatus(„Connection established.“)
''SubOrFunc_UpdateStatus("Writing to server Proc ID: " & proc.Id.ToString & ", Message: " & i_MSG)
pipeStream.Write(bytesProcID, 0, bytesProcID.Length)
pipeStream.Write(bytesMessageType, 0, bytesMessageType.Length)
pipeStream.Write(bytesMessage, 0, bytesMessage.Length)
i_ReturnValue += „Written to Server Proc ID:“ & curProcessID '& „, Message:“ & i_MSG
RaiseEvent cu_MessageSended(Me, curProcessID, MessageType, i_MSG, Now)
System.Windows.Forms.Application.DoEvents()
''SubOrFunc_UpdateStatus(„Closing connection…“)
pipeStream.Close()
''SubOrFunc_UpdateStatus(„Connection closed.“)
Catch ex As System.TimeoutException
'Do Nothing
'Alle Threads / Applications, die nicht auf die Pipe reagieren können werden ausgenommen
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
End If
System.Windows.Forms.Application.DoEvents()
’ Next ’ next process
'End If
'End If
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
Return i_ReturnValue
End Function
‚‘’
‚‘’ Verwenden Sie diese Funktion um eine Nachricht an alle Prozesse zu senden, die die Selbe Pipe benutzen.
‚‘’
‚‘’ String der gesendet wird. !Achtung! es wird immer ein Zeilenumbruch angehängt!
‚‘’ Gibt einen String zurück, in dem alle Server aufgeführt werden, die die Nachricht erhalten haben.
‚‘’
Public Function SendAtAllOnThisMachine(ByVal Msg As String, ByVal MessageType As enum_MessageType) As String
Dim i_ReturnValue As String = „“
Try
Dim i_MSG As String = Msg
If Not String.IsNullOrEmpty(i_MSG) Then
If i_MSG.Substring(i_MSG.Length - 2) = Environment.NewLine Then
i_MSG = i_MSG.Substring(0, i_MSG.Length - 2)
End If
Dim proc As Process = Process.GetCurrentProcess()
’ Dim strTrgProcessName = proc.ProcessName
’ If Me.cbxOtherInstanceInDebugger.Checked Then strTrgProcessName &= „.vshost“
’ Dim processes() As Process = Process.GetProcessesByName(strTrgProcessName)
Dim processes() As Process = Process.GetProcesses
If processes.Length > 0 Then
Dim bytesMessage() As Byte = System.Text.Encoding.Default.GetBytes(i_MSG & Environment.NewLine)
Dim bytesProcID() As Byte = System.Text.Encoding.Default.GetBytes(proc.Id.ToString & vbCrLf)
Dim bytesMessageType() As Byte = System.Text.Encoding.Default.GetBytes(MessageType & vbCrLf)
For Each p As Process In processes
If p.Id proc.Id Then ’ don’t send to self
’ Dim strServerPipeName As String = p.ProcessName & „_“ & p.Id
Dim strServerPipeName As String = m_PipenamePrev & p.Id
''SubOrFunc_UpdateStatus(„Attempting to connect to server " & strServerPipeName & „. Timeout = " & m_TimeOut.ToString & " milliseconds.“)
Dim pipeStream As System.IO.Pipes.NamedPipeClientStream = New System.IO.Pipes.NamedPipeClientStream(“.", strServerPipeName, System.IO.Pipes.PipeDirection.Out) ’ „.“=localhost
Try
pipeStream.Connect(m_TimeOut)
''SubOrFunc_UpdateStatus(„Connection established.“)
''SubOrFunc_UpdateStatus("Writing to server Proc ID: " & proc.Id.ToString & ", Message: " & i_MSG)
pipeStream.Write(bytesProcID, 0, bytesProcID.Length)
pipeStream.Write(bytesMessageType, 0, bytesMessageType.Length)
pipeStream.Write(bytesMessage, 0, bytesMessage.Length)
i_ReturnValue += „Written to server Proc ID:“ & proc.Id.ToString & „, Message:“ & i_MSG
RaiseEvent cu_MessageSended(Me, proc.Id, MessageType, i_MSG, Now)
System.Windows.Forms.Application.DoEvents()
''SubOrFunc_UpdateStatus(„Closing connection…“)
pipeStream.Close()
''SubOrFunc_UpdateStatus(„Connection closed.“)
Catch ex As System.TimeoutException
'Do Nothing
'Alle Threads / Applications, die nicht auf die Pipe reagieren können werden ausgenommen
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
End If
System.Windows.Forms.Application.DoEvents()
Next ’ next process
End If
End If
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
Return i_ReturnValue
End Function
‚‘’
‚‘’ Verwenden Sie diese Funktion nur um den Server zu beenden!!!
‚‘’
‚‘’
Public Sub SendAbort()
Try
Dim i_MSG As String = „ClosePipeNameServer“
If Not String.IsNullOrEmpty(i_MSG) Then
If i_MSG.Substring(i_MSG.Length - 2) = Environment.NewLine Then
i_MSG = i_MSG.Substring(0, i_MSG.Length - 2)
End If
Dim proc As Process = Process.GetCurrentProcess()
Dim bytesMessage() As Byte = System.Text.Encoding.Default.GetBytes(i_MSG & Environment.NewLine)
Dim bytesProcID() As Byte = System.Text.Encoding.Default.GetBytes(proc.Id.ToString & vbCrLf)
Dim bytesMessageType() As Byte = System.Text.Encoding.Default.GetBytes(enum_MessageType.RestartThisServer & vbCrLf)
Dim strServerPipeName As String = m_PipenamePrev & proc.Id
Dim pipeStream As System.IO.Pipes.NamedPipeClientStream = New System.IO.Pipes.NamedPipeClientStream(".", strServerPipeName, System.IO.Pipes.PipeDirection.Out) ’ „.“=localhost
Try
pipeStream.Connect(m_TimeOut)
pipeStream.Write(bytesProcID, 0, bytesProcID.Length)
pipeStream.Write(bytesMessageType, 0, bytesMessageType.Length)
pipeStream.Write(bytesMessage, 0, bytesMessage.Length)
'i_ReturnValue += „Written to server Proc ID:“ & proc.Id.ToString & „, Message:“ & i_MSG
RaiseEvent cu_MessageSended(Me, proc.Id, enum_MessageType.RestartThisServer, i_MSG, Now)
System.Windows.Forms.Application.DoEvents()
pipeStream.Close()
Catch ex As System.TimeoutException
'Do Nothing
'Alle Threads / Applications, die nicht auf die Pipe reagieren können werden ausgenommen
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
End If
Catch ex As Exception
RaiseEvent cu_Error(Me, ex, Now)
System.Windows.Forms.Application.DoEvents()
'Me.Co_Errorhandling1.SendErrorInfo(„co_NamedPipes_Messenger“, New StackFrame().GetMethod().Name, ex, „“)
End Try
End Sub
#End Region
End Class
End Namespace
.