Reputation: 6370
Salve! I want to exit my GUI application (vb.net 4) using a commandline parameter. I should send this from the commandline:
myapplication.exe quit
-and an already running instance of the application should exit. Now, I have a mutex detection in place so that I can only have one instance of the application running at a time. It seems that if I send a commandline, it won't work on an already running application; it will only work on one that is launching.
Upvotes: 0
Views: 8316
Reputation: 1
1- Open Project Properties(‘Project’ Menu-> Properties)
2- Choose ‘Application’ Tab-page.
3- Check on ‘Make single instance Application’ Option.
4- Click on the ‘View Application Events’ to View Application Events Module code.
https://barnamenevis.org/attachment.php?attachmentid=154139&d=1667144883
Choose ‘StartupNextInstance’ Event of Application, Then put this code(for e.x.) :
Partial Friend Class MyApplication
Dim ci As New Customer
Private Sub MyApplication_StartupNextInstance(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupN extInstanceEventArgs) Handles Me.StartupNextInstance
Dim Params() As String = e.CommandLine.ToArray
Dim Command(-1) As String
For i = 0 To Params.Length - 1
Command = Params(i).Split(":")
Select Case Command(0).ToLower
Case "/n", "/name" : ci.Name = Command(1)
Case "/f", "/family" : ci.Family = Command(1)
Case "/b", "/birthday" : ci.Birthday = Command(1)
Case "/m", "/mobile" : ci.Mobile = Command(1)
Case "/ph", "/phone" : ci.Phone = Command(1)
Case "/i", "/image" : ci.Image = Command(1)
End Select
Next
My.Forms.Form1.SetInfo(ci)
End Sub
End Class
This is the ‘Customer Class’ Code used in above Statements:
Public Class Customer
Private NameValue As String
Public Property Name() As String
Get
Return NameValue
End Get
Set(ByVal value As String)
NameValue = value
End Set
End Property
Private FamilyValue As String
Public Property Family() As String
Get
Return FamilyValue
End Get
Set(ByVal value As String)
FamilyValue = value
End Set
End Property
Private BirthdayValue As String
Public Property Birthday() As String
Get
Return BirthdayValue
End Get
Set(ByVal value As String)
BirthdayValue = value
End Set
End Property
Private MobileValue As String
Public Property Mobile() As String
Get
Return MobileValue
End Get
Set(ByVal value As String)
MobileValue = value
End Set
End Property
Private PhoneValue As String
Public Property Phone() As String
Get
Return PhoneValue
End Get
Set(ByVal value As String)
PhoneValue = value
End Set
End Property
Private ImageValue As String
Public Property Image() As String
Get
Return ImageValue
End Get
Set(ByVal value As String)
ImageValue = value
End Set
End Property End Class
Now for send any parameter as known parameter in Application ‘StartupNextInstance’ Event Procedure, You can make any program you want, anyway this code Help you to know how to make that:
Console Application:
https://barnamenevis.org/attachment.php?attachmentid=154149&stc=1&d=1667325874
Module Module1
Dim WithEvents DestinationProcess As Process
Sub Main()
Dim Command As String = ""
Dim DestinationApp As String = String.Format("{0}{1}", My.Application.Info.DirectoryPath, _
"\DestinationApp.exe")
Dim params() As String = {""}
Dim Args As String = ""
Do Until Command.ToLower = "quit"
Console.Write("Send Info>")
Command = Console.ReadLine
Console.WriteLine()
params = Command.Split(Space(1))
Select Case params(0).ToLower
Case "set", "setinfo"
Args = ""
If params.Length > 1 Then
For i = 1 To params.Length - 1
Args += params(i) + If(i = params.Length - 1, "", Space(1))
Next
DestinationProcess = Process.Start(DestinationApp, Args)
Else
Console.WriteLine("Use Set Command with Parameters {[/n:<name>] [/f:<family>] [/b:<birthday>] [/m:<mobile>] [/ph:<phone>] [/i:<image file path>]}")
End If
End Select
Console.WriteLine()
Loop
End Sub
End Module
Use Parameters:
Set /n:{Name} /f:{Family} /b:{Birthday} /m:{mobileNumber} /ph:{PhoneNumber} /i:{Image File Path}
You can also Modify Each one of this options when you want by use ‘Set’ or ‘SetInfo’ Command.
Source Application(Source Code), {Console Application}
Destination Application(Source Code), {Windows Forms Application}
Add this Code to 'StartupNextInstance' Event of Application Events:
Select Case e.CommandLine.Count
Case 1
Select Case e.CommandLine(0).ToLower
Case "quit"
End
End Select
End Select
Good luck.
Upvotes: 0
Reputation: 6370
Hello, everyone! After finding this nice post here, looking for a way that a single application would do one thing with the first instance, but the second instance would cause the first instance do something else.
The value of this is that you can (with your own, additional programming) use this to achieve the effect of sending commandline parameters to a running application. You would actually use a second instance of the app to send the commandline parameters as messages to the first instance. It works okay on my Windows XP, but I'm rather new to vb.net, so if you've any improvements, I'd like to know!
So I adapted anoriginalidea's nice example and below is my result. This is the bare-bones of it all, so you just see here the essentials of the process.
It works like this:
first add this as your sub main the mutex will check to see if your application is already running or not.
Public Sub Main()
Dim createdNew As Boolean = True
Using mutex As New Mutex(True, "TestForKalatorMutexProcess", createdNew)
If createdNew Then
InterComServer()
'BE SURE TO CHANGE myApplication TO YOUR PRIMARY FORM!
Application.Run(new myApplication)
Else
InterComClient()
application.exit()
End If
End Using
End Sub
Now Add this in a module in your application
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.ipc 'You have to add this as a reference!
Public Module intercom
#Region "-------------InterShared-------------------------------------"
Public Interface ICommunicationService
Sub SaySomething(ByVal text As String)
End Interface
#End Region
#Region "-------------InterComClient-------------------------------------"
'This will run on the second instance
Public Sub InterComClient(ByRef intercommessage As String)
Try
Dim ipcCh As New IpcChannel("myClient")
ChannelServices.RegisterChannel(ipcCh, False)
Dim obj As ICommunicationService = DirectCast(Activator.GetObject(GetType(ICommunicationService), "ipc://IPChannelName/SreeniRemoteObj"), ICommunicationService)
obj.SaySomething(intercommessage)
Thread.Sleep(1000)
ChannelServices.UnregisterChannel(ipcCh)
Catch ex As Exception
'If you use this as a way to exit your application, be sure to discard this exception
'because the InterCom Server won't be running to receive the closing of the channel
'and it will throw a "Pipe Ended" error that can't be solved.
'To "discard" the error, simply catch it and don't do anything.
'Dim errmsg As New Messenger("Exception in InterComClient" & vbCr & ex.Message)
End Try
End Sub
#End Region
#Region "-------------InterComServer-------------------------------------"
Public Class CommunicationService
Inherits MarshalByRefObject
Implements ICommunicationService
Public Sub SaySomething(ByVal whatmessage As String) Implements ICommunicationService.SaySomething
msgbox("InterCom Client Heard this : " & whatmessage)
Application.exit
End Sub
End Class
Public Sub InterComServer()
Dim ipcCh As IpcChannel
ipcCh = New IpcChannel("IPChannelName")
ChannelServices.RegisterChannel(ipcCh, False)
RemotingConfiguration.RegisterWellKnownServiceType(GetType(CommunicationService), "SreeniRemoteObj", WellKnownObjectMode.Singleton)
MsgBox("InterCom Server Reporting for Duty!")
End Sub
#End Region
End Module
[update]
Just FYI for anyone, I've used this in my application now for awhile, and it seems to work very well.
Upvotes: 1
Reputation: 10855
What you need is to setup some form of inter-process communication. When your 2nd instance is launched with command line parameters, before it terminates itself due to your single-instance mutex code, it needs to signal the 1st instance and pass the paramteres to it.
Now that being said, if the only command line paramater you are processing is ever going to be quit, then you can instead interate the running processes in the system (see System.Diagnotics.Process) and kill the 1st instance.
Upvotes: 0
Reputation: 392
What if you kept the commandline open for input and just listen for the Enter/Return key being pressed? You could then check to see whether they passed in the word quit or other program commands.
Upvotes: 0