19

コマンドライン引数を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"

問題は、最初と2番目の引数を正しく取得できることですが、最後の引数はとして取得されC:\Documentsます。

何か助けはありますか?

4

6 に答える 6

28

チェックを実行して問題を確認しました。びっくりしましたが、最初の引数の最後の \ です。

"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 のちょっとした行動で洞察が得られます。基本的なルールは次のとおりです。

  • バックスラッシュはエスケープ文字です
  • 常に引用符をエスケープする
  • 引用符の前にあるバックスラッシュのみをエスケープします。
于 2009-03-17T10:22:53.467 に答える
5

Ian Kemp の回答を追加するには

アセンブリが「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] になります。

于 2009-03-17T09:54:42.303 に答える
1

他のみんながすでに言ったことに加えて、それは逃げる問題かもしれません。別のバックスラッシュでバックスラッシュをエスケープする必要があります。

次のようなものにする必要があります:

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

于 2009-03-17T10:00:04.833 に答える
1

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;
                }
            }
于 2011-01-17T21:14:56.860 に答える
1

私は最近、同じ厄介な問題に気付き、コマンド ライン引数配列を自分で解析するパーサーを作成することにしました。

注: 問題は、static void Main(string[] args) 関数に渡される .NET CommandLine Arguments が \" と \\ をエスケープすることです。実際には、引用符または一例:

次を単一の引数として渡したいとします。

-msg:ねえ、「どこにいるの?」

例えば。

sampleapp -msg:"ねえ、\"どこにいるの?\""

デフォルトの動作で送信する方法になります。

プログラムで引用符やバックスラッシュをエスケープしなければならない理由が見当たらない場合は、以下のように独自のパーサーを使用してコマンド ラインを解析できます。

すなわち。[プログラム].exe "C:\test\" arg1 arg2

args[0] = c:\test" arg1 arg2 を持つ

args[0]=c:\test\ と、args[1]=arg1 と args[2]=arg2 が予想されます。

以下の関数は、この簡略化された動作で引数をリストに解析します。

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;
}
于 2010-05-05T10:51:19.663 に答える
0

問題は正確には何ですか?とにかく、ここにいくつかの一般的なアドバイスがあります:

Main メソッド (Program.cs 内) が次のように定義されていることを確認します。

void Main(string[] args)

args は、コマンドライン引数を含む配列です。

于 2009-03-17T09:49:29.883 に答える