我一直在使用Mutex创建单个实例应用程序。
在Sub Main
代码中,应用会检查它是否是第一个实例,如果是,则启动表单(称为MainForm
)。 MainForm
创建一个异步命名管道服务器来接收从新实例传递的参数。
如果应用程序不是第一个实例,则Sub Main会创建一个命名管道客户端,将命令行参数发送到第一个应用程序,然后继续退出。
应用程序是基于选项卡的,每个命令行参数都是一个文件路径,用于创建选项卡。接收到的论点(我可以MsgBox()
),但是当我尝试将其作为参数传递给我创建的控件时,没有任何反应
Pipe
课程:
Namespace Pipes
' Delegate for passing received message back to caller
Public Delegate Sub DelegateMessage(Reply As String)
Public Class PipeServer
Public Event PipeMessage As DelegateMessage
Private _pipeName As String
Public Sub Listen(PipeName As String)
Try
' Set to class level var so we can re-use in the async callback method
_pipeName = PipeName
' Create the new async pipe
Dim pipeServer As New NamedPipeServerStream(PipeName, PipeDirection.[In], 1, PipeTransmissionMode.[Byte], PipeOptions.Asynchronous)
' Wait for a connection
pipeServer.BeginWaitForConnection(New AsyncCallback(AddressOf WaitForConnectionCallBack), pipeServer)
Catch oEX As Exception
Debug.WriteLine(oEX.Message)
End Try
End Sub
Private Sub WaitForConnectionCallBack(iar As IAsyncResult)
Try
' Get the pipe
Dim pipeServer As NamedPipeServerStream = DirectCast(iar.AsyncState, NamedPipeServerStream)
' End waiting for the connection
pipeServer.EndWaitForConnection(iar)
Dim buffer As Byte() = New Byte(254) {}
' Read the incoming message
pipeServer.Read(buffer, 0, 255)
' Convert byte buffer to string
Dim stringData As String = Encoding.UTF8.GetString(buffer, 0, buffer.Length)
Debug.WriteLine(stringData + Environment.NewLine)
' Pass message back to calling form
RaiseEvent PipeMessage(stringData)
' Kill original sever and create new wait server
pipeServer.Close()
pipeServer = Nothing
pipeServer = New NamedPipeServerStream(_pipeName, PipeDirection.[In], 1, PipeTransmissionMode.[Byte], PipeOptions.Asynchronous)
' Recursively wait for the connection again and again....
pipeServer.BeginWaitForConnection(New AsyncCallback(AddressOf WaitForConnectionCallBack), pipeServer)
Catch
Return
End Try
End Sub
End Class
Class PipeClient
Public Sub Send(SendStr As String, PipeName As String, Optional TimeOut As Integer = 1000)
Try
Dim pipeStream As New NamedPipeClientStream(".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous)
' The connect function will indefinitely wait for the pipe to become available
' If that is not acceptable specify a maximum waiting time (in ms)
pipeStream.Connect(TimeOut)
Debug.WriteLine("[Client] Pipe connection established")
Dim _buffer As Byte() = Encoding.UTF8.GetBytes(SendStr)
pipeStream.BeginWrite(_buffer, 0, _buffer.Length, AddressOf AsyncSend, pipeStream)
Catch oEX As TimeoutException
Debug.WriteLine(oEX.Message)
End Try
End Sub
Private Sub AsyncSend(iar As IAsyncResult)
Try
' Get the pipe
Dim pipeStream As NamedPipeClientStream = DirectCast(iar.AsyncState, NamedPipeClientStream)
' End the write
pipeStream.EndWrite(iar)
pipeStream.Flush()
pipeStream.Close()
pipeStream.Dispose()
Catch oEX As Exception
Debug.WriteLine(oEX.Message)
End Try
End Sub
End Class
End Namespace
MainForm
逻辑:
#Region "Pipes"
Public ArgumentPipe As New Pipes.PipeServer
Public Sub RecievedMessage(reply As String)
GetMainformHook.Invoke(MySTDelegate, reply)
End Sub
Public Sub InitializeServer()
AddHandler ArgumentPipe.PipeMessage, AddressOf RecievedMessage
ArgumentPipe.Listen(_pipename)
End Sub
Public Delegate Sub RecievedMessageDel(txt As String)
Public MySTDelegate As RecievedMessageDel = AddressOf SetText
Public Sub SetText(txt)
MsgBox(txt)
TabStrip1.AddTab(txt.ToString) 'PROBLEM OCCURS HERE
End Sub
Public Shared Function GetMainformHook() As MainForm
Return Application.OpenForms("MainForm")
End Function
Public Shared Function GetTabControl() As TabStrip
Return CType(Application.OpenForms("MainForm"), MainForm).TabStrip1
End Function
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitializeServer()
End Sub
#End Region
发送参数时Sub Main
:
Dim _pipeClient = New Pipes.PipeClient()
If cmdArgs.Length > 0 Then
For i = 0 To cmdArgs.Length - 1
_pipeClient.Send(cmdArgs(i), _pipename, 1000)
Next
End If
_pipename
是一个全局字符串,如"myappv6"
我错过了什么吗?
我认为这与交叉线程有关,但无法确定解决问题的位置。
由于