Aquí tienes todo lo que necesitas saber:
( revisa las distintas secciones de la guía, en el panel lateral izquierdo de la página. )
El siguiente código lo puedes usar tal cual, o si lo prefieres tomarlo como un simple ejemplo que estudiar. Todo este código es un extracto reducido de mi framework comercial
ElektroKit para
.NET Framework, que si a alguien le interesa lo puede encontrar en mi firma de usuario...
Mediante la clase
CommandLineParameter se pueden representar parámetros sin valor ( ej.
/Command1 ), mediante la clase
CommandLineValueParameter(Of T) parámetros con valor ( ej.
/Path="C:\Directory\" ). Mediante la clase
CommandLineParameterCollection una coleccion de
CommandLineParameter, y por último, mediante la clase
CommandLineValueParameterCollection una coleccion de
CommandLineValueParameter(Of T).
Como puedas usar esas clases, es algo que depende de las necesidades de cada programador.
Hay tres tipos de prefijos que puedes usar al asignar el nombre del parámetro:
/Nombre \Nombre y
-NombreY dos tipos de sufijos o separadores disponibles para los parámetros con valor:
/Nombre:Valor y
/Nombre=Valor(Sí, la sintaxis está enfocada al modo de empleo de argumentos command-line en el sistema de
Microsoft Windows. )
Si por cualquier motivo no gusta o no entiendes como utilizar mi implementación, entonces puedes buscar otras en Google (que hay bastantes implementaciones en C# y VB.NET para representar argumentos command-line, la verdad).
En fin, aquí tienes el código:
''' <summary>
''' Specifies the prefix character that indicates the start of the parameter's name of a <see cref="CommandLineParameter"/>
''' </summary>
Public Enum CommandLineParameterPrefix As Integer
''' <summary>
''' The dash character "-"
''' <para></para>
''' For example: "-ParameterName"
''' </summary>
Dash = 0
''' <summary>
''' The slash character "/"
''' <para></para>
''' For example: "/ParameterName"
''' </summary>
Slash = 1
''' <summary>
''' The slash character "\"
''' <para></para>
''' For example: "\ParameterName"
''' </summary>
BackSlash = 2
End Enum
''' <summary>
''' Specifies the suffix character that delimits the parameter's name from the parameter's value of a <see cref="CommandLineParameter"/>
''' </summary>
Public Enum CommandLineParameterSuffix As Integer
''' <summary>
''' The equals sign character "="
''' <para></para>
''' For example: "/ParameterName=Value"
''' </summary>
EqualsSign = 0
''' <summary>
''' The colon character ":"
''' <para></para>
''' For example: "/ParameterName:Value"
''' </summary>
Colon = 1
End Enum
CommandLineParameter.vb#Region " Command-Line Parameter "
''' <summary>
''' Represents a command-line parameter that does not takes any value.
''' </summary>
Public Class CommandLineParameter
#Region " Properties "
''' <summary>
''' Gets or sets the prefix character that indicates the start of the parameter's name.
''' <para></para>
''' For example: "/ParameterName" where "/" is the prefix.
''' </summary>
Public Property Prefix As CommandLineParameterPrefix = CommandLineParameterPrefix.Slash
''' <summary>
''' Gets the name of the parameter.
''' </summary>
Public ReadOnly Property Name As String
Get
Return Me.nameB
End Get
End Property
Private nameB As String
''' <summary>
''' Gets or sets the short name of the parameter.
''' <para></para>
''' A short name should be an abbreviated name of the parameter. A short name is optional and can de null.
''' </summary>
Public Property ShortName As String
Get
Return shortNameB
End Get
<DebuggerStepThrough>
Set(ByVal value As String)
Me.TrySetShortName(value)
End Set
End Property
Private shortNameB As String
''' <summary>
''' Gets the full name of the parameter including the prefix.
''' <para></para>
''' For Example: "/ParameterName"
''' </summary>
Public ReadOnly Property FullName As String
Get
Return Me.ToString()
End Get
End Property
''' <summary>
''' Gets the full short name of the parameter including the prefix.
''' <para></para>
''' For Example: "/ParameterShortName"
''' </summary>
Public ReadOnly Property FullShortName As String
Get
If Not String.IsNullOrEmpty(Me.shortNameB) Then
Return String.Format("{0}{1}", Me.GetPrefixChar(), Me.shortNameB)
Else
Return Me.ToString()
End If
End Get
End Property
''' <summary>
''' Gets or sets a value indicating whether this parameter is required for the application.
''' <para></para>
''' A value of <see langword="False"/> means the user needs to pass this parameter to the application.
''' <para></para>
''' A value of <see langword="True"/> means this is an optional parameter so no matter if the user pass this parameter to the application.
''' </summary>
Public Property IsOptional As Boolean
#End Region
#Region " Constructors "
''' <summary>
''' Prevents a default instance of the <see cref="CommandLineParameter"/> class from being created.
''' </summary>
Private Sub New()
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="CommandLineParameter" /> class.
''' </summary>
''' <param name="name">
''' The name of the parameter.
''' </param>
Public Sub New(ByVal name As String)
If String.IsNullOrWhiteSpace(name) Then
Throw New ArgumentNullException()
End If
Me.TrySetName(name)
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Returns a <see cref="String"/> that represents this <see cref="CommandLineParameter"/>.
''' </summary>
Public Overloads Function ToString() As String
Return String.Format("{0}{1}", Me.GetPrefixChar(), Me.nameB)
End Function
''' <summary>
''' Gets the prefix character that indicates the start of the parameter's name.
''' <para></para>
''' For Example: "/"
''' </summary>
Public Function GetPrefixChar() As Char
Select Case Me.Prefix
Case CommandLineParameterPrefix.Dash
Return "-"c
Case CommandLineParameterPrefix.Slash
Return "/"c
Case CommandLineParameterPrefix.BackSlash
Return "\"c
Case Else
Throw New InvalidEnumArgumentException()
End Select
End Function
#End Region
#Region " Private Methods "
''' <summary>
''' Evaluates an attempt to assign the parameter name.
''' </summary>
<DebuggerStepThrough>
Protected Overridable Sub TrySetName(ByVal name As String)
For Each c As Char In name
If Not Char.IsLetterOrDigit(c) Then
Throw New ArgumentException(message:="The name of the parameter only can contain letters and digits.",
paramName:="name")
End If
Next c
Me.nameB = name
End Sub
''' <summary>
''' Evaluates an attempt to assign the short name of the parameter.
''' </summary>
<DebuggerStepThrough>
Protected Overridable Sub TrySetShortName(ByVal shortName As String)
If Not String.IsNullOrEmpty(shortName) Then
For Each c As Char In shortName
If Not Char.IsLetterOrDigit(c) Then
Throw New ArgumentException(message:="The short name of the parameter only can contain letters and digits.",
paramName:="shortName")
End If
Next c
If (shortName.Equals(Me.nameB, StringComparison.OrdinalIgnoreCase)) Then
Throw New ArgumentException(message:="The short name of the parameter cannot be equals than the parameter's name.",
paramName:="shortName")
End If
End If
Me.shortNameB = shortName
End Sub
#End Region
End Class
#End Region
CommandLineValueParameter(Of T As IConvertible).vb#Region " Command-Line Value Parameter (Of T) "
''' <summary>
''' Represents a command-line parameter that takes a value of specific <see cref="Type"/>.
''' </summary>
Public Class CommandLineValueParameter(Of T As IConvertible) : Inherits CommandLineParameter
#Region " Properties "
''' <summary>
''' Gets or sets the suffix character that delimits the parameter's name from the parameter's value.
''' <para></para>
''' For example: "/ParameterName=Value" where "/" is the prefix and "=" the suffix.
''' </summary>
Public Property Suffix As CommandLineParameterSuffix = CommandLineParameterSuffix.EqualsSign
''' <summary>
''' Gets or sets the parameter's value defined by the end-user.
''' <para></para>
''' This value should be initially <see langword="Nothing"/> before parsing the commandline arguments of the application.
''' <para></para>
''' The value of the parameter should be assigned by the end-user when passing an argument to the application.
''' <para></para>
''' To set a default value for this parameter, use <see cref="CommandLineValueParameter(Of T).DefaultValue"/> property instead.
''' </summary>
Public Property Value As T
''' <summary>
''' Gets or sets the default parameter's value.
''' <para></para>
''' This value should be take into account if, after parsing the command-line arguments of the application,
''' <see cref="CommandLineValueParameter(Of T).Value"/> is <see langword="Nothing"/>,
''' meaning that the end-user did not assigned any value to this parameter.
''' </summary>
Public Property DefaultValue As T
#End Region
#Region " Constructors "
''' <summary>
''' Initializes a new instance of the <see cref="CommandLineValueParameter(Of T)" /> class.
''' </summary>
''' <param name="name">
''' The name of the parameter.
''' </param>
Public Sub New(ByVal name As String)
MyBase.New(name)
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Returns a <see cref="String"/> that represents this <see cref="CommandLineValueParameter(Of T)"/>.
''' </summary>
Public Overloads Function ToString() As String
Return String.Format("{0}{1}""{2}""", MyBase.ToString(), Me.GetSuffixChar(),
If(Me.Value IsNot Nothing, Me.Value.ToString(Nothing), Me.DefaultValue.ToString(Nothing)))
End Function
''' <summary>
''' Gets the suffix character that delimits the parameter's name from the parameter's value.
''' <para></para>
''' For Example: "="
''' </summary>
Public Function GetSuffixChar() As Char
Select Case Me.Suffix
Case CommandLineParameterSuffix.Colon
Return ":"c
Case CommandLineParameterSuffix.EqualsSign
Return "="c
Case Else
Throw New InvalidEnumArgumentException()
End Select
End Function
#End Region
#Region " Operator Conversion "
''' <summary>
''' Performs an implicit conversion from <see cref="CommandLineValueParameter(Of IConvertible)"/> to <see cref="CommandLineValueParameter(Of T)"/>.
''' </summary>
<DebuggerStepThrough>
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of IConvertible)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of IConvertible)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of String)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of String)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Char)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Char)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Boolean)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Boolean)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Date)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Date)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Byte)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Byte)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of SByte)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of SByte)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Short)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Short)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of UShort)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of UShort)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Integer)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Integer)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of UInteger)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of UInteger)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Long)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Long)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of ULong)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of ULong)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Single)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Single)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Double)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Double)(cmd)
End Operator
Public Shared Widening Operator CType(ByVal cmd As CommandLineValueParameter(Of Decimal)) As CommandLineValueParameter(Of T)
Return CommandLineValueParameter(Of T).ConvertCommandLineValueParameter(Of Decimal)(cmd)
End Operator
#End Region
#Region " Private Methods "
''' <summary>
''' Converts a <see cref="CommandLineValueParameter(Of IConvertible)"/> to <see cref="CommandLineValueParameter(Of T)"/>.
''' </summary>
Private Shared Function ConvertCommandLineValueParameter(Of I As IConvertible)(ByVal cmd As CommandLineValueParameter(Of I)) As CommandLineValueParameter(Of T)
Return New CommandLineValueParameter(Of T)(cmd.Name) With
{
.Prefix = cmd.Prefix,
.Suffix = cmd.Suffix,
.ShortName = cmd.ShortName,
.DefaultValue = DirectCast(CObj(cmd.DefaultValue), T),
.Value = DirectCast(CObj(cmd.Value), T),
.IsOptional = cmd.IsOptional
}
End Function
#End Region
End Class
#End Region
CommandLineParameterCollection.vb#Region " CommandLineParameter Collection "
''' <summary>
''' Represents a strongly typed list of <see cref="CommandLineParameter"/> that can be accessed by an index.
''' </summary>
<Serializable>
<XmlRoot("Items")>
<DebuggerDisplay("Count = {Count}")>
<DefaultMember("Item")>
Public Class CommandLineParameterCollection :
Inherits Collection(Of CommandLineParameter
)
#Region " Constructors "
Public Sub New()
End Sub
#End Region
#Region " Indexers "
''' <summary>
''' Gets or sets the <see cref="CommandLineParameter"/> that matches the specified key name.
''' </summary>
''' <param name="paramName">
''' The parameter name.
''' </param>
Default Public Overloads Property Item(ByVal paramName As String) As CommandLineParameter
<DebuggerStepThrough>
Get
Return Me.Find(paramName)
End Get
<DebuggerStepThrough>
Set(ByVal value As CommandLineParameter)
Me(Me.IndexOf(paramName)) = value
End Set
End Property
#End Region
#Region " Public Methods "
''' <summary>
''' Adds a <see cref="CommandLineParameter"/> to the end of the <see cref="CommandLineParameterCollection"/>.
''' </summary>
<DebuggerStepThrough>
Public Shadows Sub Add(ByVal param As CommandLineParameter)
If Me.Contains(param.Name) OrElse Me.Contains(param.ShortName) Then
Throw New ArgumentException(message:="Parameter already exists.", paramName:="refParam")
Else
MyBase.Add(param)
End If
End Sub
''' <summary>
''' Adds the specified parameters to the end of the <see cref="CommandLineParameterCollection"/>.
''' </summary>
<DebuggerStepThrough>
Public Shadows Sub AddRange(ByVal params As CommandLineParameter())
For Each param As CommandLineParameter In params
Me.Add(param)
Next param
End Sub
Public Shadows Sub Remove(ByVal param As CommandLineParameter)
Dim indexOf As Integer = Me.IndexOf(param)
If (indexOf = -1) Then
Throw New ArgumentException(message:="Parameter doesn't exists.", paramName:="param")
Else
MyBase.RemoveAt(indexOf)
End If
End Sub
Public Shadows Sub Remove(ByVal name As String)
Dim indexOf As Integer = Me.IndexOf(name)
If (indexOf = -1) Then
Throw New ArgumentException(message:="Parameter doesn't exists.", paramName:="name")
Else
MyBase.RemoveAt(indexOf)
End If
End Sub
''' <summary>
''' Determines whether the <see cref="CommandLineParameterCollection"/> contains a <see cref="CommandLineParameter"/> that
''' matches the specified key name.
''' </summary>
''' <returns>
''' <see langword="True"/> if the <see cref="CommandLineParameterCollection"/> contains the <see cref="CommandLineParameter"/>,
''' <see langword="False"/> otherwise.
''' </returns>
<DebuggerStepThrough>
Public Overloads Function Contains(ByVal name As String) As Boolean
Return (From param As CommandLineParameter In MyBase.Items
Where param.Name.Equals(name, StringComparison.OrdinalIgnoreCase) OrElse
param.ShortName.Equals(name, StringComparison.OrdinalIgnoreCase)).Any
End Function
''' <summary>
''' Searches for an <see cref="CommandLineParameter"/> that matches the specified parameter name,
''' and returns the first occurrence within the entire <see cref="CommandLineParameterCollection"/>.
''' </summary>
<DebuggerStepThrough>
Public Overloads Function Find(ByVal name As String) As CommandLineParameter
Return (From param As CommandLineParameter In MyBase.Items
Where param.Name.Equals(name, StringComparison.OrdinalIgnoreCase) OrElse
param.ShortName.Equals(name, StringComparison.OrdinalIgnoreCase)).
DefaultIfEmpty(Nothing).
SingleOrDefault()
End Function
''' <summary>
''' Searches for an <see cref="CommandLineParameter"/> that matches the specified key name and
''' returns the zero-based index of the first occurrence within the entire <see cref="CommandLineParameterCollection"/>.
''' </summary>
''' <returns>
''' The zero-based index of the first occurrence of <see cref="CommandLineParameter"/> within the entire <see cref="CommandLineParameterCollection"/>, if found;
''' otherwise, <c>–1</c>.
''' </returns>
<DebuggerStepThrough>
Public Overloads Function IndexOf(ByVal name As String) As Integer
Dim index As Integer = 0
Dim found As Boolean = False
For Each param As CommandLineParameter In Me.Items
If param.Name.Equals(name, StringComparison.OrdinalIgnoreCase) OrElse
param.ShortName.Equals(name, StringComparison.OrdinalIgnoreCase) Then
found = True
Exit For
End If
index += 1
Next param
If (found) Then
Return index
Else
Return -1
End If
End Function
#End Region
End Class
#End Region
CommandLineValueParameterCollection.vb#Region " CommandLineValueParameter Collection "
''' <summary>
''' Represents a strongly typed list of <see cref="CommandLineValueParameter"/> that can be accessed by an index.
''' </summary>
<Serializable>
<XmlRoot("Items")>
<DebuggerDisplay("Count = {Count}")>
<DefaultMember("Item")>
Public Class CommandLineValueParameterCollection :
Inherits Collection(Of CommandLineValueParameter
(Of IConvertible
))
#Region " Constructors "
Public Sub New()
End Sub
#End Region
#Region " Indexers "
''' <summary>
''' Gets or sets the <see cref="CommandLineValueParameter"/> that matches the specified key name.
''' </summary>
''' <param name="name">
''' The parameter name.
''' </param>
Default Public Overloads Property Item(ByVal name As String) As CommandLineValueParameter(Of IConvertible)
<DebuggerStepThrough>
Get
Dim result As CommandLineValueParameter(Of IConvertible) = Me.Find(name)
If (result Is Nothing) Then
Throw New NullReferenceException(message:="Item not found with the specified name.")
End If
Return result
End Get
<DebuggerStepThrough>
Set(ByVal value As CommandLineValueParameter(Of IConvertible))
Me(Me.IndexOf(name)) = value
End Set
End Property
#End Region
#Region " Public Methods "
Public Shadows Sub Add(ByVal param As CommandLineValueParameter(Of IConvertible))
If Me.Contains(param.Name) OrElse Me.Contains(param.ShortName) Then
Throw New ArgumentException(message:="Parameter already exists.", paramName:="param")
Else
MyBase.Add(refParam)
End If
End Sub
Public Shadows Sub AddRange(ByVal params As CommandLineValueParameter(Of IConvertible)())
For Each param As CommandLineValueParameter(Of IConvertible) In params
Me.Add(param)
Next param
End Sub
Public Shadows Sub Remove(ByVal param As CommandLineValueParameter(Of IConvertible))
Dim indexOf As Integer = Me.IndexOf(param)
If (indexOf = -1) Then
Throw New ArgumentException(message:="Parameter doesn't exists.", paramName:="param")
Else
MyBase.RemoveAt(indexOf)
End If
End Sub
Public Shadows Sub Remove(ByVal name As String)
Dim indexOf As Integer = Me.IndexOf(name)
If (indexOf = -1) Then
Throw New ArgumentException(message:="Parameter doesn't exists.", paramName:="name")
Else
MyBase.RemoveAt(indexOf)
End If
End Sub
''' <summary>
''' Determines whether the <see cref="CommandLineValueParameterCollection"/> contains a <see cref="CommandLineValueParameter"/> that
''' matches the specified key name.
''' </summary>
''' <returns>
''' <see langword="True"/> if the <see cref="CommandLineValueParameterCollection"/> contains the <see cref="CommandLineValueParameter"/>,
''' <see langword="False"/> otherwise.
''' </returns>
<DebuggerStepThrough>
Public Overloads Function Contains(ByVal name As String) As Boolean
Return (From param As CommandLineValueParameter(Of IConvertible) In MyBase.Items
Where param.Name.Equals(name, StringComparison.OrdinalIgnoreCase) OrElse
param.ShortName.Equals(name, StringComparison.OrdinalIgnoreCase)).Any
End Function
''' <summary>
''' Searches for an <see cref="CommandLineValueParameter"/> that matches the specified parameter name,
''' and returns the first occurrence within the entire <see cref="CommandLineValueParameterCollection"/>.
''' </summary>
<DebuggerStepThrough>
Public Overloads Function Find(ByVal name As String) As CommandLineValueParameter(Of IConvertible)
Return (From param As CommandLineValueParameter(Of IConvertible) In MyBase.Items
Where param.Name.Equals(name, StringComparison.OrdinalIgnoreCase) OrElse
param.ShortName.Equals(name, StringComparison.OrdinalIgnoreCase)).
DefaultIfEmpty(Nothing).
SingleOrDefault()
End Function
''' <summary>
''' Searches for an <see cref="CommandLineValueParameter"/> that matches the specified key name and
''' returns the zero-based index of the first occurrence within the entire <see cref="CommandLineValueParameterCollection"/>.
''' </summary>
''' <returns>
''' The zero-based index of the first occurrence of <see cref="CommandLineValueParameter"/> within the entire <see cref="CommandLineValueParameterCollection"/>, if found;
''' otherwise, <c>–1</c>.
''' </returns>
<DebuggerStepThrough>
Public Overloads Function IndexOf(ByVal name As String) As Integer
Dim index As Integer = 0
Dim found As Boolean = False
For Each param As CommandLineValueParameter(Of IConvertible) In Me.Items
If param.Name.Equals(name, StringComparison.OrdinalIgnoreCase) OrElse
param.ShortName.Equals(name, StringComparison.OrdinalIgnoreCase) Then
found = True
Exit For
End If
index += 1
Next param
If (found) Then
Return index
Else
Return -1
End If
End Function
#End Region
End Class
#End Region
Un ejemplo de uso:
Module Module1
Dim params As New CommandLineValueParameterCollection From {
New CommandLineValueParameter(Of String)("ParameterName1") With {
.Prefix = CommandLineParameterPrefix.Slash,
.Suffix = CommandLineParameterSuffix.EqualsSign,
.ShortName = "Param1",
.DefaultValue = "",
.IsOptional = False
},
New CommandLineValueParameter(Of Boolean)("ParameterName2") With {
.Prefix = CommandLineParameterPrefix.Slash,
.Suffix = CommandLineParameterSuffix.EqualsSign,
.ShortName = "Param2",
.DefaultValue = False,
.IsOptional = True
},
New CommandLineValueParameter(Of Integer)("ParameterName3") With {
.Prefix = CommandLineParameterPrefix.Slash,
.Suffix = CommandLineParameterSuffix.EqualsSign,
.ShortName = "Param3",
.DefaultValue = -1I,
.IsOptional = True
}
}
Public Function IsParameterAssignedInArgument(Of T As IConvertible)(ByVal parameter As CommandLineValueParameter(Of T), ByVal argument As String) As Boolean
Return (argument.StartsWith(parameter.FullName & parameter.GetSuffixChar(), StringComparison.OrdinalIgnoreCase) OrElse
argument.StartsWith(parameter.FullShortName & parameter.GetSuffixChar(), StringComparison.OrdinalIgnoreCase))
End Function
Public Sub SetParameterValue(Of T As IConvertible)(ByRef parameter As CommandLineValueParameter(Of T), ByVal argument As String)
If IsParameterAssignedInArgument(parameter, argument) Then
Dim value As String = argument.Substring(argument.IndexOf(parameter.GetSuffixChar()) + 1).Trim({ControlChars.Quote})
If String.IsNullOrEmpty(value) Then
parameter.Value = parameter.DefaultValue
Else
Try
parameter.Value = DirectCast(Convert.ChangeType(value, parameter.DefaultValue.GetType()), T)
Catch ex As InvalidCastException
Throw
Catch ex As FormatException
Throw
End Try
End If
End If
End Sub
Sub Main()
' Parse command-line arguments to set the values of the parameters.
ParseArguments(params, AddressOf OnSyntaxError, AddressOf OnMissingParameterRequired)
' Display the parameters and each value assigned.
For Each param As CommandLineValueParameter(Of IConvertible) In params
Console.WriteLine(param.ToString())
Next
End Sub
''' <summary>
''' Loop through all the command-line arguments of this application.
''' </summary>
Friend Sub ParseArguments(ByVal cmds As CommandLineValueParameterCollection,
ByVal callbackSyntaxError As Action(Of CommandLineValueParameter(Of IConvertible)),
ByVal callbackMissingRequired As Action(Of CommandLineValueParameter(Of IConvertible)))
ParseArguments(cmds, Environment.GetCommandLineArgs.Skip(1), callbackSyntaxError, callbackMissingRequired)
End Sub
Friend Sub ParseArguments(ByVal cmds As CommandLineValueParameterCollection,
ByVal args As IEnumerable(Of String),
ByVal callbackSyntaxError As Action(Of CommandLineValueParameter(Of IConvertible)),
ByVal callbackMissingRequired As Action(Of CommandLineValueParameter(Of IConvertible)))
If Not (args.Any) Then
PrintHelp()
End If
' Required parameters. Not optional ones.
Dim cmdRequired As List(Of CommandLineValueParameter(Of IConvertible)) =
(From cmd As CommandLineValueParameter(Of IConvertible) In cmds
Where Not cmd.IsOptional).ToList()
For Each arg As String In args
For Each cmd As CommandLineValueParameter(Of IConvertible) In cmds
If arg.Equals("/?") Then
PrintHelp()
End If
If IsParameterAssignedInArgument(cmd, arg) Then
If (cmdRequired.Contains(cmd)) Then
cmdRequired.Remove(cmd)
End If
Try
SetParameterValue(Of IConvertible)(cmd, arg)
Catch ex As Exception
callbackSyntaxError.Invoke(cmd)
End Try
End If
Next cmd
Next arg
If (cmdRequired.Any) Then
callbackMissingRequired.Invoke(cmdRequired.First())
End If
End Sub
Friend Sub OnSyntaxError(ByVal cmd As CommandLineValueParameter(Of IConvertible))
Console.WriteLine(String.Format("[X] Syntax error in parameter: {0})", cmd.FullName))
Environment.Exit(exitCode:=1)
End Sub
Friend Sub OnMissingParameterRequired(ByVal cmd As CommandLineValueParameter(Of IConvertible))
Console.WriteLine(String.Format("[X] Parameter {0} is required. ", cmd.FullName))
Environment.Exit(exitCode:=1)
End Sub
Friend Sub PrintHelp()
Dim sb As New StringBuilder
sb.AppendLine("Commands Help:")
For Each param As CommandLineValueParameter(Of IConvertible) In params
sb.AppendFormat("{0} {{{1}}}", param.FullName, param.DefaultValue.GetType().Name)
sb.AppendLine()
Next
Console.WriteLine(sb.ToString())
Environment.Exit(exitCode:=1)
End Sub
End Module
Resultados de ejecución:
Ayuda del programa:
ConsoleApp1.exe /?
Commands Help:
/ParameterName1 {String}
/ParameterName2 {Boolean}
/ParameterName3 {Int32}
Error-handling de parametros requeridos no especificados:
ConsoleApp1.exe /param2=true /param3=100
[X] Parameter "/ParameterName1" is required.
Error-handling de fallos en el parsing de valores:
ConsoleApp1.exe /param2=nul
[X] Syntax error in parameter: /ParameterName2 {Boolean}
Resultado de asignación de valores de cada parámetro tras un parsing exitoso de los argumentos command-line:
ConsoleApp1.exe /param1="hello world" /param2=true /param3=100
/ParameterName1="hello world"
/ParameterName2="True"
/ParameterName3="100"
PD: El código de arriba es solo un ejemplo, se puede extender para controlar nombres de parámetros que no existen y/o nombres repetidos, por ejemplo.
Saludos.