Home > Software design >  Command line Argument at Runtime using single instance application
Command line Argument at Runtime using single instance application

Time:09-22

I'm developing a small tools to receive command line argument. Argument is send during runtime. I found from this article :

and try to implemented using startupnextinstance events

my code is like this on ApplicationEvents

 Partial Friend Class MyApplication
        Private Sub MyApplication_StartupNextInstance(sender As Object, e As StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
            Dim f = Application.MainForm
            If f.GetType Is GetType(Form1) Then
               CType(f, Form1).NewArgumentsReceived(e.CommandLine.ToArray)
            End If
        End Sub
    End Class

and in form1, I'm using this code:

Public Class Form1
    Dim strFile As String = "d:\temp.txt"
    Dim fileExists As Boolean = File.Exists(strFile)
    Public Sub NewArgumentsReceived(args As String())
        If args.Length > 0 Then
            Using sw As New StreamWriter(strFile)
                sw.WriteLine(args(0), Environment.NewLine)
                sw.Flush()
            End Using
        End If
    End Sub
End Class

I'm trying to send output to file (just for debugging). When I'm try to run this application, I can't receive the argument that send to this tools (temp file is empty) also my tools in not run in single instance again

My purpose is read command line argument that send at runtime and can read at every where form.

Any wrong with my code? Why single instance application is not working in here?

CodePudding user response:

Based on my testing, it seems like there might be a bug in the single-instance application functionality when running in the debugger that causes the third and subsequent instances to throw an exception but it seems to work properly when running the application directly. Code-wise, I added this to Form1:

Public Sub DoSomething(args As IEnumerable(Of String))
    MessageBox.Show(String.Join(Environment.NewLine, args))
End Sub

and this to ApplicationEvents.vb:

Private Sub MyApplication_StartupNextInstance(sender As Object, e As StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
    TryCast(MainForm, Form1)?.DoSomething(e.CommandLine)
End Sub

In the project properties, I edited the Debug Launch Profiles and set the Command line arguments to "First Second Third" (without quotes). I then right-clicked on the project and selected Debug -> Start Without Debugging multiples times and all but the first instance displayed the expected message box. I was also able to start the app from a command prompt with commandline arguments and it worked as expected then too.

It's also worth noting that that event is not raised on the UI thread, so you may find that the message box in my example behaves a little strangely. In a real app, you should marshal a call to the UI thread to do something in Form1 in most cases, e.g.

Private Sub MyApplication_StartupNextInstance(sender As Object, e As StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
    Dim f1 = DirectCast(MainForm, Form1)

    f1.Invoke(Sub() f1.DoSomething(e.CommandLine))
End Sub

That will make the message box in my example behave modally with respect to the form, which it doesn't if it's displayed on a different thread.

  • Related