示例代码解决的问题:
在C#中解析命令行参数的最佳方法?
C#命令行参数解析类以及使用实例
一个用于解析命令行参数的库。
标准化地解析命令行
C#程序处理命令行参数
C#的命令行参数
C#命令行解析工具
关键字
C# 解析 命令行 cmd .bat
namespace System
{
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
public class CommandLineHelper
{
private const char QueotedChar = '\"';
///
/// 解析命令行中参数。
///
///
/// 支持解析示例(保留最后1个值):
///
/// { "/a:100", "-b:200", "/c=300", "/c1", "/c2", "/d", "400", "Unknow+d:400", "/e", "500", "end" }
///
/// { "Unknow+100", "Unknow+200", "/a:100", "-b:200", "/c=300", "/c1", "/c2", "/d", "400", "Unknow+d:400", "/e", "500", "end" }
///
/// { "/", "Unknow+100", "/", "Unknow+200", "/", "Unknow+d:400", "/", "end", "/a", "100" }
///
///
///
public static Dictionary GetSwitchDictionary(string[] args, int startIndex = 0, string switchNameFirstKey = null)
{
return GetSwitchDictionary(args, startIndex, switchNameFirstKey, new char[] { '-', '/' }, new char[] { '=', ':' }, true);
}
public static Dictionary GetSwitchDictionary(string[] args, int startIndex, string switchNameFirstKey, char[] switchChars, char[] keyValueSplitChars, bool ignoreCase)
{
string switchName = string.Empty;
bool switchNameWrited = true;
string switchNameFirst = null;
List charList = new List(switchChars);
StringComparer comparer;
if (ignoreCase)
comparer = StringComparer.CurrentCultureIgnoreCase;
else
comparer = StringComparer.CurrentCulture;
Dictionary info = new Dictionary(args.Length + 1, comparer);
for (int i = startIndex; i < args.Length; i++)
{
var param = args[i];
if (param.Length >= 1 && charList.Contains(param[0]))
{
// 如果上1个参数名称没有写入集合。
if (!switchNameWrited && switchName != null)
{
string switchValue = null;
info[switchName] = switchValue;
if (switchNameFirst == null) switchNameFirst = switchName;
}
string paramStr = param.Substring(1).Trim();
int keyValueSplitIndex = -1;
if (keyValueSplitChars != null && keyValueSplitChars.Length > 0)
{
keyValueSplitIndex = paramStr.IndexOfAny(keyValueSplitChars);
}
// 如果同时存在参数名称和参数值。
if (keyValueSplitIndex >= 0)
{
switchName = paramStr.Substring(0, keyValueSplitIndex);
var switchValueIndex = switchName.Length + 1;
string switchValue = paramStr.Substring(switchValueIndex);
info[switchName] = switchValue;
switchNameWrited = true;
if (switchNameFirst == null) switchNameFirst = switchName;
// 参数名称和参数值都写入集合后,重置参数名称。
// 作用:确保能够读出没有参数名称的默认参数值。
switchName = string.Empty;
}
// 如果只存在参数名称。
else
{
switchName = paramStr;
switchNameWrited = false;
}
}
// 如果key为 "" ,也写入集合。
// 作用:确保能够读出没有参数名称的默认参数值。
else if (switchName != null)
{
string switchValue = param;
info[switchName] = switchValue;
switchNameWrited = true;
if (switchNameFirst == null) switchNameFirst = switchName;
// 参数名称和参数值都写入集合后,重置参数名称。
// 作用:确保能够读出没有参数名称的默认参数值。
switchName = string.Empty;
}
}
// 如果上1个参数名称没有写入集合。
if (!switchNameWrited && switchName != null)
{
string switchValue = null;
info[switchName] = switchValue;
if (switchNameFirst == null) switchNameFirst = switchName;
}
if (switchNameFirstKey != null)
{
info[switchNameFirstKey] = switchNameFirst;
}
return info;
}
///
/// 解析命令行中参数。
///
///
/// 支持解析示例(保留所有值):
///
/// { "/a:100", "-b:200", "/c=300", "/c1", "/c2", "/d", "400", "Unknow+d:400", "/e", "500", "end" }
///
/// { "Unknow+100", "Unknow+200", "/a:100", "-b:200", "/c=300", "/c1", "/c2", "/d", "400", "Unknow+d:400", "/e", "500", "end" }
///
/// { "/", "Unknow+100", "/", "Unknow+200", "/", "Unknow+d:400", "/", "end", "/a", "100" }
///
///
///
public static NameValueCollection GetSwitchCollection(string[] args, int startIndex = 0, string switchNameFirstKey = null)
{
return GetSwitchCollection(args, startIndex, switchNameFirstKey, new char[] { '-', '/' }, new char[] { '=', ':' }, true);
}
public static NameValueCollection GetSwitchCollection(string[] args, int startIndex, string switchNameFirstKey, char[] switchChars, char[] keyValueSplitChars, bool ignoreCase)
{
string switchName = string.Empty;
bool switchNameWrited = true;
string switchNameFirst = null;
List charList = new List(switchChars);
StringComparer comparer;
if (ignoreCase)
comparer = StringComparer.CurrentCultureIgnoreCase;
else
comparer = StringComparer.CurrentCulture;
NameValueCollection info = new NameValueCollection(args.Length + 1, comparer);
for (int i = startIndex; i < args.Length; i++)
{
var param = args[i];
if (param.Length >= 1 && charList.Contains(param[0]))
{
// 如果上1个参数名称没有写入集合。
if (!switchNameWrited && switchName != null)
{
string switchValue = null;
info.Add(switchName, switchValue);
if (switchNameFirst == null) switchNameFirst = switchName;
}
string paramStr = param.Substring(1).Trim();
int keyValueSplitIndex = -1;
if (keyValueSplitChars != null && keyValueSplitChars.Length > 0)
{
keyValueSplitIndex = paramStr.IndexOfAny(keyValueSplitChars);
}
// 如果同时存在参数名称和参数值。
if (keyValueSplitIndex >= 0)
{
switchName = paramStr.Substring(0, keyValueSplitIndex);
var switchValueIndex = switchName.Length + 1;
string switchValue = paramStr.Substring(switchValueIndex);
info.Add(switchName, switchValue);
switchNameWrited = true;
if (switchNameFirst == null) switchNameFirst = switchName;
// 参数名称和参数值都写入集合后,重置参数名称。
// 作用:确保能够读出没有参数名称的默认参数值。
switchName = string.Empty;
}
// 如果只存在参数名称。
else
{
switchName = paramStr;
switchNameWrited = false;
}
}
// 如果key为 "" ,也写入集合。
// 作用:确保能够读出没有参数名称的默认参数值。
else if (switchName != null)
{
string switchValue = param;
info.Add(switchName, switchValue);
switchNameWrited = true;
if (switchNameFirst == null) switchNameFirst = switchName;
// 参数名称和参数值都写入集合后,重置参数名称。
// 作用:确保能够读出没有参数名称的默认参数值。
switchName = string.Empty;
}
}
// 如果上1个参数名称没有写入集合。
if (!switchNameWrited && switchName != null)
{
string switchValue = null;
info.Add(switchName, switchValue);
if (switchNameFirst == null) switchNameFirst = switchName;
}
if (switchNameFirstKey != null)
{
info.Add(switchNameFirstKey, switchNameFirst);
}
return info;
}
public static bool CheckSwitch(string[] args, int startIndex, string switchName, bool defaultValue)
{
string switchValue;
bool value = defaultValue;
bool isFind = FindSwitch(args, startIndex, switchName, out switchValue);
if (isFind)
{
value = ValueToBoolean(switchValue, defaultValue);
}
return value;
}
public static bool ValueToBoolean(string switchValue, bool defaultValue)
{
bool value = defaultValue;
// 如果值是空白或者新的参数的名称。
if (string.IsNullOrEmpty(switchValue))
{
value = true;
}
else
{
string lowerValue = switchValue.TrimStart(' ', ':', '=').ToLower();
switch (lowerValue)
{
case "0":
case "false":
value = false;
break;
case "1":
case "true":
value = true;
break;
}
}
return value;
}
public static bool FindSwitch(string[] args, int startIndex, string switchName, out string switchValue)
{
return FindSwitch(args, startIndex, switchName, new char[] { '-', '/' }, true, out switchValue);
}
public static bool FindSwitch(string[] args, int startIndex, string switchName, char[] switchChars, bool ignoreCase, out string switchValue)
{
bool result = false;
switchValue = string.Empty;
List charList = new List(switchChars);
StringComparison comparison = StringComparison.CurrentCulture;
if (ignoreCase)
comparison = StringComparison.CurrentCultureIgnoreCase;
for (int i = startIndex; i < args.Length; i++)
{
var param = args[i];
if (param.Length > 1 && charList.Contains(param[0]))
{
string paramStr = param.Substring(1).Trim();
if (paramStr.StartsWith(switchName, comparison)
&& (paramStr.Length >= switchName.Length))
{
result = true;
switchValue = paramStr.Substring(switchName.Length);
if (!string.IsNullOrEmpty(switchValue))
return true;
}
// 如果已经找到对应的命令行,再次找到其它命名行开始的标志,就退出查找。
// 避免命令行,使用其它命令行的值的问题。
else if (result)
{
break;
}
}
else if (result)
{
switchValue = param;
break;
}
}
return result;
}
public static string GetCommandLineString(ICollection> parameters, char switchChar = '/')
{
return GetCommandLineString(parameters, switchChar, ' ', false);
}
public static string GetCommandLineString(ICollection> parameters, char switchChar, char keyValueSplitChar, bool mustQueoted)
{
var space = ' ';
var builder = new StringBuilder(100);
if (keyValueSplitChar == ' ')
{
foreach (KeyValuePair item in parameters)
{
var parameterItem = switchChar + item.Key;
if (!string.IsNullOrEmpty(parameterItem))
{
var needQueoted = mustQueoted || parameterItem.IndexOf(' ') >= 0;
if (needQueoted)
{
parameterItem = QueotedChar + parameterItem + QueotedChar;
}
if (builder.Length > 0) builder.Append(space);
builder.Append(parameterItem);
}
parameterItem = item.Value;
if (!string.IsNullOrEmpty(parameterItem))
{
var needQueoted = mustQueoted || parameterItem.IndexOf(' ') >= 0;
if (needQueoted)
{
parameterItem = QueotedChar + parameterItem + QueotedChar;
}
if (builder.Length > 0) builder.Append(space);
builder.Append(parameterItem);
}
}
}
else
{
foreach (KeyValuePair item in parameters)
{
var parameterItem = switchChar + item.Key + keyValueSplitChar + item.Value;
if (!string.IsNullOrEmpty(parameterItem))
{
var needQueoted = mustQueoted || parameterItem.IndexOf(' ') >= 0;
if (needQueoted)
{
parameterItem = QueotedChar + parameterItem + QueotedChar;
}
if (builder.Length > 0) builder.Append(space);
builder.Append(parameterItem);
}
}
}
return builder.ToString();
}
public static string GetCommandLineString(NameValueCollection parameters, char switchChar = '/')
{
return GetCommandLineString(parameters, switchChar, ' ', false);
}
public static string GetCommandLineString(NameValueCollection parameters, char switchChar, char keyValueSplitChar, bool mustQueoted)
{
var space = ' ';
var builder = new StringBuilder(100);
if (keyValueSplitChar == ' ')
{
foreach (object itemKeyObj in parameters.Keys)
{
string itemKey = itemKeyObj?.ToString();
if (itemKey != null)
{
var itemValues = parameters.GetValues(itemKey);
if (itemValues != null)
{
foreach (var itemValue in itemValues)
{
var parameterItem = switchChar + itemKey;
if (!string.IsNullOrEmpty(parameterItem))
{
var needQueoted = mustQueoted || parameterItem.IndexOf(' ') >= 0;
if (needQueoted)
{
parameterItem = QueotedChar + parameterItem + QueotedChar;
}
if (builder.Length > 0) builder.Append(space);
builder.Append(parameterItem);
}
parameterItem = itemValue;
if (!string.IsNullOrEmpty(parameterItem))
{
var needQueoted = mustQueoted || parameterItem.IndexOf(' ') >= 0;
if (needQueoted)
{
parameterItem = QueotedChar + parameterItem + QueotedChar;
}
if (builder.Length > 0) builder.Append(space);
builder.Append(parameterItem);
}
}
}
}
}
}
else
{
foreach (object itemKeyObj in parameters.Keys)
{
string itemKey = itemKeyObj?.ToString();
if (itemKey != null)
{
var itemValues = parameters.GetValues(itemKey);
if (itemValues != null)
{
foreach (var itemValue in itemValues)
{
var parameterItem = switchChar + itemKey + keyValueSplitChar + itemValue;
if (!string.IsNullOrEmpty(parameterItem))
{
var needQueoted = mustQueoted || parameterItem.IndexOf(' ') >= 0;
if (needQueoted)
{
parameterItem = QueotedChar + parameterItem + QueotedChar;
}
if (builder.Length > 0) builder.Append(space);
builder.Append(parameterItem);
}
}
}
}
}
}
return builder.ToString();
}
///
/// 将特定的参数名和值移动到末尾。
/// 或者将特定的参数名移动到末尾(如果没有对应的值)。
///
///
///
///
///
public static IList MoveNotQueotedPairToEnd(IList notQueotedList, string switchName, bool ignoreCase = true)
{
List newNotQueotedList;
List movedNotQueotedList;
SplitMovedNotQueotedPair(notQueotedList, switchName, ignoreCase,
out newNotQueotedList, out movedNotQueotedList);
newNotQueotedList.AddRange(movedNotQueotedList);
return newNotQueotedList;
}
///
/// 将特定的参数名和值移除。
/// 或者将特定的参数名移除(如果没有对应的值)。
///
///
///
///
///
public static IList DeleteNotQueotedPair(IList notQueotedList, string switchName, bool ignoreCase = true)
{
List newNotQueotedList;
List movedNotQueotedList;
SplitMovedNotQueotedPair(notQueotedList, switchName, ignoreCase,
out newNotQueotedList, out movedNotQueotedList);
return newNotQueotedList;
}
private static void SplitMovedNotQueotedPair(IList notQueotedList, string switchName, bool ignoreCase,
out List newNotQueotedList, out List movedNotQueotedList)
{
newNotQueotedList = new List(notQueotedList.Count);
movedNotQueotedList = new List(2);
List charList = new List(new char[] { '-', '/' });
StringComparison comparison = ignoreCase ?
StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture;
bool isValueBegin = false;
for (int i = 0; i < notQueotedList.Count; i++)
{
bool isMovedParam = false;
var param = notQueotedList[i];
if (!string.IsNullOrEmpty(param) && charList.Contains(param[0]))
{
string paramStr = param.Substring(1).Trim();
if (paramStr.EndsWith(switchName, comparison))
{
movedNotQueotedList.Add(param);
isValueBegin = true;
isMovedParam = true;
}
// 如果已经找到对应的命令行,再次找到其它命名行开始的标志,就退出查找值。
// 避免命令行,使用其它命令行的值的问题。
else if (isValueBegin)
{
isValueBegin = false;
}
}
else if (isValueBegin)
{
movedNotQueotedList.Add(param);
isMovedParam = true;
}
if (!isMovedParam)
{
newNotQueotedList.Add(param);
}
}
}
}
}