簡體   English   中英

在 C# 中傳遞命令行 arguments

[英]Passing command-line arguments in C#

我正在嘗試將命令行 arguments 傳遞給 C# 應用程序,但我在傳遞類似這樣的東西時遇到問題

"C:\Documents and Settings\All Users\Start Menu\Programs\App name"

即使我在論點中添加" "

這是我的代碼:

    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)
            {
            }
        }
        }

這就是我要傳遞的內容:

C:\WINDOWS\Uninstaller.exe  "C:\Program Files\Application name\"  "username"  "C:\Documents and Settings\All Users\Start Menu\Programs\application name"

問題是我可以正確獲取第一個和第二個參數,但最后一個參數是C:\Documents

有什么幫助嗎?

我只是進行了檢查並驗證了問題。 它讓我感到驚訝,但它是第一個參數中的最后一個 \ 。

"C:\Program Files\Application name\" <== remove the last '\'

這需要更多解釋,有人有想法嗎? 我傾向於稱其為錯誤。


第 2 部分,我又進行了一些測試,然后

"X:\\aa aa\\" "X:\\aa aa\" next

變成

X:\\aa aa\
X:\\aa aa" next

喬恩·加洛韋 (Jon Galloway) 的博客中, Google 的一些小動作給出了一些見解,基本規則是:

  • 反斜杠是轉義字符
  • 總是轉義引號
  • 僅在引號之前轉義反斜杠。

添加伊恩坎普的答案

如果您的程序集名為“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"

字符串“C:\Documents and Settings\All Users\Start Menu\Programs\App name”

將在 args[0]。

我最近注意到同樣煩人的問題,並決定自己編寫一個解析器來解析命令行 arguments 數組。

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一個例子:

假設您想將以下內容作為單個參數傳遞:

-msg:嘿,“你在哪里?”

例如。

sampleapp -msg:"嘿,\"你在哪里?\""

將是如何以默認行為發送它。

如果您沒有看到任何人必須為您的程序轉義引號或反斜杠的理由,您可以使用自己的解析器來解析命令行,如下所示。

IE。 [程序].exe "C:\test\" arg1 arg2

會有一個 args[0] = c:\test" arg1 arg2

你所期望的是 args[0]=c:\test\ 然后是 args[1]=arg1 和 args[2]=arg2。

下面的 function 將 arguments 解析為具有此簡化行為的列表。

請注意,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;
}

在回應 WWC 的回答時,Jamezor 評論說,如果第一個字符是引號,他的代碼將失敗。

要解決該問題,您可以將 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;
                }
            }

補充一下其他人已經說過的,這可能是一個 escaping 問題。 你應該用另一個反斜杠來轉義你的反斜杠。

應該是這樣的:

C:\>myprog.exe "C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\App name"

究竟是什么問題? 無論如何,這里有一些一般性建議:

確保您的 Main 方法(在 Program.cs 中)定義為:

void Main(string[] args)

然后 args 是一個包含命令行 arguments 的數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM