在 C# 中传递命令行参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/653563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing command-line arguments in C#
提问by
I'm trying to pass command-line arguments to a C# application, but I have problem passing something like this
我正在尝试将命令行参数传递给 C# 应用程序,但我在传递类似这样的内容时遇到问题
"C:\Documents and Settings\All Users\Start Menu\Programs\App name"
even if I add " "
to the argument.
即使我添加" "
到论点。
Here is my code:
这是我的代码:
public ObjectModel(String[] args)
{
if (args.Length == 0) return; //no command line arg.
//System.Windows.Forms.MessageBox.Show(args.Length.ToString());
//System.Windows.Forms.MessageBox.Show(args[0]);
//System.Windows.Forms.MessageBox.Show(args[1]);
//System.Windows.Forms.MessageBox.Show(args[2]);
//System.Windows.Forms.MessageBox.Show(args[3]);
if (args.Length == 3)
{
try
{
RemoveInstalledFolder(args[0]);
RemoveUserAccount(args[1]);
RemoveShortCutFolder(args[2]);
RemoveRegistryEntry();
}
catch (Exception e)
{
}
}
}
And here is what I'm passing:
这是我要传递的内容:
C:\WINDOWS\Uninstaller.exe "C:\Program Files\Application name\" "username" "C:\Documents and Settings\All Users\Start Menu\Programs\application name"
The problem is I can get the first and the second args correctly, but the last one it gets as C:\Documents
.
问题是我可以正确地获得第一个和第二个参数,但最后一个它作为C:\Documents
.
Any help?
有什么帮助吗?
采纳答案by Henk Holterman
I just ran a check and verified the problem. It surprised me, but it is the last \ in the first argument.
我刚刚进行了检查并验证了问题。这让我感到惊讶,但它是第一个参数中的最后一个 \。
"C:\Program Files\Application name\" <== remove the last '\'
This needs more explanation, does anybody have an idea? I'm inclined to call it a bug.
这需要更多解释,有人有想法吗?我倾向于称其为错误。
Part 2, I ran a few more tests and
第 2 部分,我又进行了一些测试
"X:\aa aa\" "X:\aa aa\" next
becomes
变成
X:\aa aa\
X:\aa aa" next
A little Google action gives some insight from a blog by Jon Galloway, the basic rules are:
谷歌的一个小动作从Jon Galloway的博客中提供了一些见解,基本规则是:
- the backslash is the escape character
- always escape quotes
- only escape backslashes when they precede a quote.
- 反斜杠是转义字符
- 总是逃避报价
- 只有在引用之前转义反斜杠。
回答by Ian Kemp
What exactly is the problem? Anyway here's some general advice:
究竟是什么问题?无论如何,这里有一些一般性建议:
Make sure your Main method (in Program.cs) is defined as:
确保您的 Main 方法(在 Program.cs 中)定义为:
void Main(string[] args)
Then args is an array containing the command-line arguments.
然后 args 是一个包含命令行参数的数组。
回答by Johnno Nolan
To add Ian Kemp's answer
添加 Ian Kemp 的答案
If you assembly is called "myProg.exe" and you pass in the string "C:\Documents and Settings\All Users\Start Menu\Programs\App name" link so
如果您的程序集名为“myProg.exe”并且您传入字符串“C:\Documents and Settings\All Users\Start Menu\Programs\App name”链接,则
C:\>myprog.exe "C:\Documents and Settings\All Users\Start Menu\Programs\App name"
the string "C:\Documents and Settings\All Users\Start Menu\Programs\App name"
字符串“C:\Documents and Settings\All Users\Start Menu\Programs\App name”
will be at args[0].
将在 args[0]。
回答by Aamir
To add to what everyone else has already said, It might be an escaping problem. You should escape your backslashes by another backslash.
补充一下其他人已经说过的,这可能是一个逃避问题。你应该用另一个反斜杠来逃避你的反斜杠。
Should be something like:
应该是这样的:
C:\>myprog.exe "C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\App name"
C:\>myprog.exe "C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\App name"
回答by WWC
I noticed the same annoying issue recently, and decided to write a parser to parse the command line arguments array out myself.
我最近注意到了同样烦人的问题,并决定自己编写一个解析器来解析命令行参数数组。
Note: the issue is that the .NET CommandLine Arguments passed to the static void Main(string[] args) function escapes \" and \\. This is by design, since you may actually want to pass an argument that has a quote or backslash in it. One example:
注意:问题是传递给 static void Main(string[] args) 函数的 .NET CommandLine Arguments 转义了 \" 和 \\。这是设计使然,因为您可能实际上想要传递一个带有引号或反斜杠在里面。一个例子:
say you wanted to pass the following as a single argument:
假设您想将以下内容作为单个参数传递:
-msg:Hey, "Where you at?"
-msg:嘿,“你在哪里?”
eg.
例如。
sampleapp -msg:"Hey, \"Where you at?\""
sampleapp -msg:"嘿,\"你在哪里?\""
Would be how to send it with the default behavior.
将是如何使用默认行为发送它。
If you don't see a reason for anyone to have to escape quotes or backslashes for your program, you could utilize your own parser to parse the command line, as below.
如果您没有看到任何人必须为您的程序转义引号或反斜杠的理由,您可以使用自己的解析器来解析命令行,如下所示。
IE. [program].exe "C:\test\" arg1 arg2
IE。[程序].exe "C:\test\" arg1 arg2
would have a args[0] = c:\test" arg1 arg2
会有一个 args[0] = c:\test" arg1 arg2
What you would expect is args[0]=c:\test\ and then args[1]=arg1 and args[2]=arg2.
您所期望的是 args[0]=c:\test\,然后是 args[1]=arg1 和 args[2]=arg2。
The below function parses the arguments into a list with this simplified behavior.
下面的函数将参数解析为具有这种简化行为的列表。
Note, arg[0] is the program name using the below code. (You call List.ToArray() to convert the resulting list to a string array.)
注意,arg[0] 是使用以下代码的程序名称。(您调用 List.ToArray() 将结果列表转换为字符串数组。)
protected enum enumParseState : int { StartToken, InQuote, InToken };
public static List<String> ManuallyParseCommandLine()
{
String CommandLineArgs = Environment.CommandLine.ToString();
Console.WriteLine("Command entered: " + CommandLineArgs);
List<String> listArgs = new List<String>();
Regex rWhiteSpace = new Regex("[\s]");
StringBuilder token = new StringBuilder();
enumParseState eps = enumParseState.StartToken;
for (int i = 0; i < CommandLineArgs.Length; i++)
{
char c = CommandLineArgs[i];
// Console.WriteLine(c.ToString() + ", " + eps);
//Looking for beginning of next token
if (eps == enumParseState.StartToken)
{
if (rWhiteSpace.IsMatch(c.ToString()))
{
//Skip whitespace
}
else
{
token.Append(c);
eps = enumParseState.InToken;
}
}
else if (eps == enumParseState.InToken)
{
if (rWhiteSpace.IsMatch(c.ToString()))
{
Console.WriteLine("Token: [" + token.ToString() + "]");
listArgs.Add(token.ToString().Trim());
eps = enumParseState.StartToken;
//Start new token.
token.Remove(0, token.Length);
}
else if (c == '"')
{
// token.Append(c);
eps = enumParseState.InQuote;
}
else
{
token.Append(c);
eps = enumParseState.InToken;
}
}
//When in a quote, white space is included in the token
else if (eps == enumParseState.InQuote)
{
if (c == '"')
{
// token.Append(c);
eps = enumParseState.InToken;
}
else
{
token.Append(c);
eps = enumParseState.InQuote;
}
}
}
if (token.ToString() != "")
{
listArgs.Add(token.ToString());
Console.WriteLine("Final Token: " + token.ToString());
}
return listArgs;
}
回答by guesser
In response to WWC's answer, Jamezor commented that his code will fail if the first character is a quote.
在回应 WWC 的回答时,Jamezor 评论说,如果第一个字符是引号,他的代码将失败。
To fix that problem, you can replace the StartToken case with this:
为了解决这个问题,你可以用这个替换 StartToken 案例:
if (eps == enumParseState.StartToken)
{
if (rWhiteSpace.IsMatch(c.ToString()))
{
//Skip whitespace
}
else if (c == '"')
{
eps = enumParseState.InQuote;
}
else
{
token.Append(c);
eps = enumParseState.InToken;
}
}