2009-03-17 16 views
16

staram się przekazywać argumenty wiersza polecenia do aplikacji C#, ale mam problemy przechodzącą coś jak tenUboczny argumenty wiersza polecenia w języku C#

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

nawet jeśli dodam " " do argumentu.

Oto mój kod:

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

A oto co ja uchwala:

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

Problemem jest to, mogę dostać pierwsze i drugie argumenty poprawnie, ale ostatni robi się jako C:\Documents.

Każda pomoc?

+1

Co chcesz zacząć od tego?Wiersz poleceń lub inny program? Jeśli to drugie - jaki jest język? – sharptooth

+0

Co stanie się, gdy przekażesz taki argument do swojej aplikacji? – Draco

+0

Czy możesz przekroczyć kod, który próbuje uzyskać dostęp do argumentu, a także pełny wiersz polecenia, który wpisujesz, na przykład c: \ myapp.exe "c: \ documents \ appname" –

Odpowiedz

25

Właśnie sprawdził i zweryfikował problem. Zaskoczyło mnie to, ale jest ostatnim \ w pierwszym argumencie.

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

To wymaga więcej wyjaśnień, czy ktoś ma pomysł? Jestem skłonny nazwać to błędem.


Część 2, wpadłem jeszcze kilka testów i

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

staje

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

trochę akcji Google daje pewien wgląd od A blog by Jon Galloway podstawowe zasady to:

  • backslash jest es peleryna postać
  • zawsze unikaj cytatów
  • Unikaj tylko ukośników, gdy poprzedzają cytat.
+0

Naprawiono to przez usunięcie \ z pierwszego argumentu. Dzięki za dużo –

+0

Jeśli chcesz ten końcowy ukośnik odwrotny, możesz dodać inny. \ "w linii poleceń powoduje argument" abd \ ". –

+0

@Jim: Tak, pierwsza część przykładu pokazuje, że: –

0

Na czym dokładnie polega problem? W każdym razie oto kilka ogólnych rad:

Upewnij się, że główna metoda (w Program.cs) jest zdefiniowany jako:

void Main(string[] args) 

Then args jest tablicą zawierającą argumenty wiersza polecenia.

5

Aby dodać odpowiedź Ian Kemp

Jeśli zespół nazywa się "myProg.exe" i przejść w ciągu "C: \ Documents and Settings \ All Users \ Menu Start \ Programy nazwa \ App" link tak

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

ciąg "C: \ Documents and Settings \ All Users \ Menu Start \ Programy nazwa \ App"

będzie w args [0].

+3

Jednak: w przypadku, gdy wywołasz 'myprog.exe" c: \ one \ "" dwa "" trzy "', wówczas argumenty [0] będą miały postać 'c: \ one" two three' .Spróbuj out! –

1

Aby dodać do tego, co wszyscy już powiedzieli, może to być uciekający problem. Powinieneś uciec przed backslashes przez inny backslash.

Powinno być coś takiego:

C: \> myprog.exe "C: \\ Documents and Settings \\ Users \\ Wszystkie Menu Start \\ Programy \\ nazwa aplikacji"

+0

Wystarczająco dziwny to jest ostatni lewy ukośnik w pierwszym argumencie Sprawdziłem: –

+1

Ale podwójne \\ są nonsensem na wejściu, są użyteczne tylko w źródle C# –

+0

ale działają :) spróbuj – Aamir

1

Ostatnio zauważyłem ten sam denerwujący problem i postanowiłem napisać parser, aby samemu przetworzyć zawartość tablicy argumentów z linii poleceń.

Uwaga: problem polega na tym, że argumenty Command Line Argumenty sieci .NET przekazane do funkcji static void Main (string [] args) powodują zaniknięcie \ "i \\. Jest to zgodne z projektem, ponieważ możesz chcieć przekazać argument, że ma cytatów lub ukośnik w nim jednym z przykładów.

powiedzieć chciałeś przekazać następujące jako pojedynczy argument:

-msg: „gdzie jesteś” Hej,

np.

sampleapp -msg: "Hej, \" Gdzie na \ ""

Byłoby jak wysłać go z domyślnego zachowania?.

Jeśli nie widzisz powodu, dla którego ktokolwiek musiałby uciec przed cudzysłowami lub ułamkami ukośnymi twojego programu, możesz użyć własnego parsera do parsowania wiersza poleceń, jak poniżej.

IE. [Program] .exe "C: \ test \" arg1 arg2

miałoby args [0] = c: \ test”arg1 arg2

Czego można oczekiwać jest args [0] = c: \ \ test a następnie arg [1] = arg1 i argumentów [2] = arg2.

poniżej funkcja analizuje argumenty na liście z tego uproszczonego postępowania.

Uwaga Arg [0] jest program nazwa za pomocą poniższego kodu. (Wywołujesz List.ToArray(), aby przekształcić wynikową listę w tablicę znaków.)

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; 
} 
+1

to wydaje się łamać, jeśli pierwsza postać jest cytatem – Jamezor

+0

@Jamezor - Ty "w porządku. Zobacz moją odpowiedź na korektę. – guesser

1

W odpowiedzi na odpowiedź WWC, Jamezor skomentował, że jego kod nie powiedzie się, jeśli pierwsza postać jest cytatem.

Aby rozwiązać ten problem, można wymienić przypadek StartToken z tym:

  if (eps == enumParseState.StartToken) 
      { 
       if (rWhiteSpace.IsMatch(c.ToString())) 
       { 
        //Skip whitespace 
       } 
       else if (c == '"') 
       { 
        eps = enumParseState.InQuote; 
       } 
       else 
       { 
        token.Append(c); 
        eps = enumParseState.InToken; 
       } 
      } 
Powiązane problemy