שתף באמצעות


VB.NET Console App with Arguments

Question

Friday, August 23, 2019 8:14 PM

I'm learning about VB.NET Console Apps but I find that arguments are not very clear to me. What I'd like to do is run the .exe with a switch like WIMP.exe -u kurtcobain. I then want to store the user name in a variable in the program. I may add other switches later. Thanks for your help in advance.

All replies (3)

Friday, August 23, 2019 9:14 PM | 1 vote

Hello,

Check out the following post, specifically the reply that is not the answer but the one directly below it. Then if that does not work for you know that the first post is a library and I generally stay away from libraries such as this one.

https://stackoverflow.com/questions/13463744/parse-multiple-named-command-line-parameters

Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow


Saturday, August 24, 2019 12:03 PM

Hello,

Here is another path to consider. The code below comes from a C# article which converted to VB.NET as shown may work for you.

Add this class to your project

Public Class InputArguments
#Region "fields & properties"
    Public Const DEFAULT_KEY_LEADING_PATTERN As String = "-"

    Protected _parsedArguments As New Dictionary(Of String, String)(StringComparer.OrdinalIgnoreCase)
    Protected ReadOnly _keyLeadingPattern As String

    Default Public Property Item(key As String) As String
        Get
            Return GetValue(key)
        End Get
        Set(ByVal value As String)
            If key IsNot Nothing Then
                _parsedArguments(key) = value
            End If
        End Set
    End Property
    Public ReadOnly Property KeyLeadingPattern() As String
        Get
            Return _keyLeadingPattern
        End Get
    End Property
#End Region

#Region "public methods"
    Public Sub New(args() As String, pkeyLeadingPattern As String)
        _keyLeadingPattern = If(Not String.IsNullOrEmpty(pkeyLeadingPattern), pkeyLeadingPattern, DEFAULT_KEY_LEADING_PATTERN)

        If args IsNot Nothing AndAlso args.Length > 0 Then
            Parse(args)
        End If
    End Sub
    Public Sub New(args() As String)
        Me.New(args, Nothing)
    End Sub

    Public Function Contains(key As String) As Boolean
        Dim adjustedKey As String = Nothing
        Return ContainsKey(key, adjustedKey)
    End Function

    Public Overridable Function GetPeeledKey(key As String) As String
        Return If(IsKey(key), key.Substring(_keyLeadingPattern.Length), key)
    End Function
    Public Overridable Function GetDecoratedKey(ByVal key As String) As String
        Return If(Not IsKey(key), (_keyLeadingPattern & key), key)
    End Function
    Public Overridable Function IsKey(str As String) As Boolean
        Return str.StartsWith(_keyLeadingPattern)
    End Function
#End Region

#Region "internal methods"
    Protected Overridable Sub Parse(args() As String)
        For index As Integer = 0 To args.Length - 1
            If args(index) Is Nothing Then
                Continue For
            End If

            Dim key As String = Nothing
            Dim val As String = Nothing

            If IsKey(args(index)) Then
                key = args(index)

                If index + 1 < args.Length AndAlso Not IsKey(args(index + 1)) Then
                    val = args(index + 1)
                    index += 1
                End If
            Else
                val = args(index)
            End If

            ' adjustment
            If key Is Nothing Then
                key = val
                val = Nothing
            End If
            _parsedArguments(key) = val
        Next
    End Sub

    Protected Overridable Function GetValue(key As String) As String
        Dim adjustedKey As String = Nothing
        If ContainsKey(key, adjustedKey) Then
            Return _parsedArguments(adjustedKey)
        End If

        Return Nothing
    End Function

    Protected Overridable Function ContainsKey(ByVal key As String, <Runtime.InteropServices.Out()> ByRef adjustedKey As String) As Boolean
        adjustedKey = key

        If _parsedArguments.ContainsKey(key) Then
            Return True
        End If

        If IsKey(key) Then
            Dim peeledKey As String = GetPeeledKey(key)
            If _parsedArguments.ContainsKey(peeledKey) Then
                adjustedKey = peeledKey
                Return True
            End If
            Return False
        End If

        Dim decoratedKey As String = GetDecoratedKey(key)
        If _parsedArguments.ContainsKey(decoratedKey) Then
            adjustedKey = decoratedKey
            Return True
        End If
        Return False
    End Function
#End Region
End Class

Now select project properties of the project, select Application tab, click "View Application events", replace the existing code with the code below.

Imports Microsoft.VisualBasic.ApplicationServices

Namespace My
    Partial Friend Class MyApplication
        ''' <summary>
        ''' Property to get command arguments
        ''' </summary>
        ''' <returns></returns>
        Public ReadOnly Property CommandLineArguments As String()
            Get
                Return Environment.GetCommandLineArgs
            End Get
        End Property
        ''' <summary>
        ''' Used to get command argument count
        ''' </summary>
        ''' <returns></returns>
        Public ReadOnly Property HasCommandLineArguments As Boolean
            Get
                Return CommandLineArguments.Length > 1
            End Get
        End Property
        Private _userName As String
        Public ReadOnly Property UserName() As String
            Get
                Return _userName
            End Get
        End Property
        Private _web_Address As String
        Public ReadOnly Property WebAddress() As String
            Get
                Return _web_Address
            End Get
        End Property
        Private _IsAdministrator As Boolean
        Public ReadOnly Property Administrator As Boolean
            Get
                Return _IsAdministrator
            End Get
        End Property
        Private _ItemValues As String()
        Public ReadOnly Property Items() As String()
            Get
                Return _ItemValues
            End Get
        End Property

        ''' <summary>
        ''' Process them as you want.
        ''' </summary>
        ''' <param name="sender"></param>
        ''' <param name="e"></param>
        Private Sub MyApplication_Startup(sender As Object, e As StartupEventArgs) _
            Handles Me.Startup

            If HasCommandLineArguments Then

                Dim arguments As InputArguments = New InputArguments(
                    CommandLineArguments)

                If arguments.Contains("-u") Then
                    _userName = arguments.Item("-u")
                End If

                If arguments.Contains("-f") Then
                    If arguments.Item("-f").Contains(" ") Then
                        _ItemValues = arguments.Item("-f").Split(" "c)
                    End If
                End If

                If arguments.Contains("-address") Then
                    _web_Address = arguments.Item("-address")
                End If

                If arguments.Contains("-admin") Then
                    _IsAdministrator = True
                End If
            End If
        End Sub
    End Class
End Namespace

In form load

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        If Not String.IsNullOrWhiteSpace(My.Application.UserName) Then
            Console.WriteLine(My.Application.UserName)
        End If

        If My.Application.Items IsNot Nothing Then
            For Each item As String In My.Application.Items
                Console.WriteLine(item)
            Next
        End If
    End Sub

End Class

Add this to test everything.

-u kurtcobain -f  "one two three" -Address http://www.google.com -admin

Results in the IDE Output window

kurtcobain
one
two
three

Note when an argument has spaces they must be enclosed in quotes as per above. 

Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow


Sunday, August 25, 2019 7:42 AM

You can just use Environment.GetCommandLineArgs

or MS wrote the following class :

'
'  This file is part of the Microsoft .NET Framework SDK Code Samples.
' 
'  Copyright (C) Microsoft Corporation.  All rights reserved.
' 
'This source code is intended only as a supplement to Microsoft
'Development Tools and/or on-line documentation.  See these other
'materials for detailed information regarding Microsoft code samples.
' 
'THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
'KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
'IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
'PARTICULAR PURPOSE.
'


'=====================================================================
'  File:      ArgumentParser.vb
'
'  Summary:   Reusable class for parsing command-line arguments.
'
'=====================================================================*/

Option Explicit On
Option Strict On


Imports System
Imports System.Globalization

Namespace Microsoft.Samples
    Public MustInherit Class ArgumentParser
        Private switchChars() As String   ' For example: "/", "-"
        Private switchSymbols() As String           ' Switch character(s)
        Private caseSensitiveSwitches As Boolean    ' Are switches case-sensitive?

        ' Domain of results when processing a command-line argument switch
        Public Enum SwitchStatus
            NoError
            YesError
            ShowUsage
        End Enum 'SwitchStatus


        ' Constructor that defaults to case-insensitive switches and 
        ' defaults to "/" and "-" as the only valid switch characters
        Protected Sub New(ByVal switchSymbols() As String)
            MyClass.New(switchSymbols, False, New String() {"/", "-"})
        End Sub 'New



        ' Constructor that defaults to "/" and "-" as the only valid switch characters
        Protected Sub New(ByVal switchSymbols() As String, ByVal caseSensitiveSwitches As Boolean)
            MyClass.New(switchSymbols, caseSensitiveSwitches, New String() {"/", "-"})
        End Sub 'New



        ' Constructor with no defaults
        Protected Sub New(ByVal switchSymbols() As String, ByVal caseSensitiveSwitches As Boolean, ByVal switchChars() As String)
            Me.switchSymbols = switchSymbols
            Me.caseSensitiveSwitches = caseSensitiveSwitches
            Me.switchChars = switchChars
        End Sub 'New



        ' Every derived class must implement an OnUsage method
        Public MustOverride Sub OnUsage(ByVal errorInfo As String)


        ' Every derived class must implement an OnSwitch method or a switch is considered an error
        Protected Overridable Function OnSwitch(ByVal switchSymbol As String, ByVal switchValue As String) As SwitchStatus
            Return SwitchStatus.YesError
        End Function 'OnSwitch



        ' Every derived class must implement an OnNonSwitch method or a non-switch is considerred an error
        Protected Overridable Function OnNonSwitch(ByVal value As String) As SwitchStatus
            Return SwitchStatus.YesError
        End Function 'OnNonSwitch



        ' The derived class is notified after all command-line switches have been parsed.
        ' The derived class can perform any sanity checking required at this time.
        Protected Overridable Function OnDoneParse() As SwitchStatus
            ' By default, we'll assume that all parsing was successful
            Return SwitchStatus.YesError
        End Function 'OnDoneParse



        ' This Parse method always parses the application's command-line arguments
        Public Overloads Function Parse() As Boolean
            ' Visual Basic will use this method since its entry-point function 
            ' doesn't get the command-line arguments passed to it.
            Return Parse(Environment.GetCommandLineArgs())
        End Function 'Parse



        ' This Parse method parses an arbitrary set of arguments
        Public Overloads Function Parse(ByVal args() As String) As Boolean
            Dim ss As SwitchStatus = SwitchStatus.NoError ' Assume parsing is sucessful.
            Dim ArgNum As Integer
            For ArgNum = 0 To (args.Length - 1)

                If Not (ss = SwitchStatus.NoError) Then Exit For

                ' Determine if this argument starts with a valid switch character
                Dim fIsSwitch As Boolean = False
                Dim n As Integer
                For n = 0 To (switchChars.Length - 1)
                    If (fIsSwitch = True) Then Exit For
                    fIsSwitch = (0 = String.CompareOrdinal(args(ArgNum), 0, switchChars(n), 0, 1))
                Next n

                If fIsSwitch Then
                    ' Does the switch begin with a legal switch symbol?
                    Dim fLegalSwitchSymbol As Boolean = False
                    For n = 0 To (switchSymbols.Length - 1) ' re-using local var n to traverse an entirely seperate loop
                        If caseSensitiveSwitches Then
                            fLegalSwitchSymbol = (0 = String.CompareOrdinal(args(ArgNum), 1, switchSymbols(n), 0, switchSymbols(n).Length))
                        Else
                            fLegalSwitchSymbol = (0 = String.CompareOrdinal(args(ArgNum).ToUpper(CultureInfo.InvariantCulture), 1, switchSymbols(n).ToUpper(CultureInfo.InvariantCulture), 0, switchSymbols(n).Length))
                        End If
                        If fLegalSwitchSymbol Then
                            Exit For
                        End If
                    Next n
                    If Not fLegalSwitchSymbol Then
                        ' User specified an unrecognized switch, exit
                        ss = SwitchStatus.YesError
                        Exit For
                    Else
                        ' This is a legal switch, notified the derived class of this switch and its value
                        If (caseSensitiveSwitches) Then
                            ss = OnSwitch(switchSymbols(n), args(ArgNum).Substring((1 + switchSymbols(n).Length)))
                        Else
                            ss = OnSwitch(switchSymbols(n).ToLower(CultureInfo.InvariantCulture), args(ArgNum).Substring((1 + switchSymbols(n).Length)))
                        End If
                    End If
                Else
                    ' This is not a switch, notified the derived class of this "non-switch value"
                    ss = OnNonSwitch(args(ArgNum))
                End If
            Next ArgNum

            ' Finished parsing arguments
            If ss = SwitchStatus.NoError Then
                ' No error occurred while parsing, let derived class perform a 
                ' sanity check and return an appropraite status
                ss = OnDoneParse()
            End If

            If ss = SwitchStatus.ShowUsage Then
                ' Status indicates that usage should be shown, show it
                OnUsage(Nothing)
            End If

            If ss = SwitchStatus.YesError Then
                ' Status indicates that an error occurred, show it and the proper usage
                If (ArgNum = args.Length) Then
                    OnUsage(Nothing)
                Else
                    OnUsage(args(ArgNum))
                End If
            End If

            ' Return whether all parsing was sucessful.
            Return ss = SwitchStatus.NoError
        End Function 'Parse
    End Class 'ArgumentParser
End Namespace

'/////////////////////////////// End of File /////////////////////////////////