bgmCoder
bgmCoder

Reputation: 6370

How to send a command to a running application via commandline

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

Answers (4)

vblover
vblover

Reputation: 1

In Visual Basic .Net Windows Forms Application, These steps must be done at first:

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


Then...

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.

Download Demo...

Source Application(Source Code), {Console Application}

Destination Application(Source Code), {Windows Forms Application}


If you want to use Command Prompt or Registry Command for Send Command to your own-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

bgmCoder
bgmCoder

Reputation: 6370

Easy Send Message to Running Instance of Application

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:

  1. First, stick this here module in your application.
  2. Then launch app1
  3. you will get a message saying, "InterCom Server Reporting for Duty!"
  4. now launch app2 - you will get a message (it is actually from app1!), saying "My name is really Bob!" to let you know that the function fired off.
  5. then app2 will exit (you told it to in sub main) and then app1 will exit becuase app2 told it to exit when InterComClient() was called.

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

tcarvin
tcarvin

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

Rachel McMahan
Rachel McMahan

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

Related Questions