2009-03-17 46 views
16

Tôi đang cố gắng để vượt qua đối số dòng lệnh để một ứng dụng C#, nhưng tôi có vấn đề đi qua một cái gì đó như thế nàyĐi qua đối số dòng lệnh trong C#

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

thậm chí nếu tôi thêm " " để lập luận.

Đây là mã của tôi:

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

Và đây là những gì tôi đang đi qua:

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

Vấn đề là tôi có thể nhận được là người đầu tiên và thứ hai args một cách chính xác, nhưng người cuối cùng nó được gọi là C:\Documents.

Bất kỳ trợ giúp nào?

+1

Bạn đang cố gắng để bắt đầu này từ đâu?Dòng lệnh hoặc chương trình khác? Nếu sau này - ngôn ngữ là gì? – sharptooth

+0

Điều gì sẽ xảy ra khi bạn chuyển một đối số như thế này vào ứng dụng của bạn? – Draco

+0

Bạn có thể bỏ qua mã của bạn để cố truy cập đối số cũng như dòng lệnh đầy đủ mà bạn đang gõ, chẳng hạn như c: \ myapp.exe "c: \ documents \ appname" –

Trả lời

25

Tôi chỉ chạy kiểm tra và xác minh sự cố. Nó làm tôi ngạc nhiên, nhưng nó là \ cuối cùng trong đối số đầu tiên.

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

Điều này cần giải thích thêm, không ai có ý tưởng? Tôi có khuynh hướng gọi đó là lỗi.hơn


Phần 2, tôi chạy một vài kiểm tra và

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

trở thành

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

Một hành động nhỏ Google cung cấp cho một số cái nhìn sâu sắc từ một blog by Jon Galloway, các quy tắc cơ bản là:

  • dấu gạch chéo ngược là es ký tự cape
  • luôn thoát báo giá
  • chỉ thoát khỏi dấu gạch chéo ngược khi chúng đứng trước báo giá.
+0

Đó là cố định bằng cách loại bỏ \ từ arg đầu tiên.Thanks alot –

+0

Nếu bạn muốn dấu gạch chéo ngược, bạn có thể thêm một dấu gạch chéo khác. \ "trên dòng lệnh kết quả trong một đối số của" abd \ " –

+0

@Jim: Có, phần đầu tiên của ví dụ chứng minh rằng: –

0

Chính xác thì vấn đề là gì? Dù sao đây là một số lời khuyên chung:

Hãy chắc chắn rằng phương pháp chính của bạn (trong Program.cs) được định nghĩa là:

void Main(string[] args) 

Sau đó args là một mảng chứa các đối số dòng lệnh.

5

Để thêm Ian Kemp của câu trả lời

Nếu bạn lắp ráp được gọi là "myProg.exe" và bạn vượt qua trong chuỗi "C: \ Documents and Settings \ All Users \ Start Menu \ Programs \ App tên" liên kết để

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

chuỗi "C: \ Documents and Settings \ All Users \ Start menu \ Programs tên \ App"

sẽ có mặt tại args [0].

+3

Tuy nhiên: trường hợp trong tay là nếu bạn gọi 'myprog.exe" c: \ one \ "" hai "" ba "', thì args [0] sẽ là 'c: \ one" hai ba'. Hãy thử –

1

Để thêm vào những gì mọi người khác đã nói, Đây có thể là sự cố thoát. Bạn nên thoát khỏi dấu gạch chéo ngược của bạn bằng dấu gạch chéo ngược khác.

nên được một cái gì đó như:

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

+0

Hoàn toàn đủ _is_ dấu gạch chéo ngược cuối cùng trong đối số 1. Tôi đã kiểm tra –

+1

Nhưng double \\ là vô nghĩa khi nhập, chúng chỉ hữu dụng trong nguồn C# –

+0

nhưng chúng hoạt động :) thử nó – Aamir

1

Tôi đã nhận thấy cùng một vấn đề gây phiền nhiễu gần đây và quyết định viết một trình phân tích cú pháp để phân tích cú pháp đối số dòng lệnh.

Lưu ý: vấn đề là các đối số NET CommandLine được chuyển đến hàm void chính (string [] args) escape \ "và \\. Đây là do thiết kế, vì bạn thực sự có thể muốn chuyển một đối số có một câu trích dẫn hoặc dấu chéo ngược trong nó một ví dụ:.

nói rằng bạn muốn vượt qua sau khi một cuộc tranh luận duy nhất:

-msg: "trong trường hợp bạn tại" Hey,

ví dụ:

SampleApp -msg: "Này, \" Nơi bạn tại \ ""

Sẽ là làm thế nào để gửi nó với hành vi mặc định?.

Nếu bạn không thấy lý do để bất kỳ ai phải thoát khỏi dấu ngoặc kép hoặc dấu gạch chéo ngược cho chương trình của mình, bạn có thể sử dụng trình phân tích cú pháp của riêng mình để phân tích cú pháp dòng lệnh như dưới đây.

IE. [chương trình] .exe "C: \ test \" arg1 arg2

sẽ có một args [0] = c: \ test" arg1 arg2

gì bạn mong chờ là args [0] = c: \ test \ và sau đó args [1] = arg1 và args [2] = arg2.

hàm dưới đây phân tích các đối số vào một danh sách với hành vi đơn giản này.

Note, arg [0] là chương trình bằng cách sử dụng mã bên dưới. (Bạn gọi List.ToArray() để chuyển đổi danh sách kết quả thành một mảng chuỗi.)

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

điều này dường như bị phá vỡ nếu ký tự đầu tiên là báo giá – Jamezor

+0

@Jamezor - Bạn đúng rồi. Xem câu trả lời của tôi cho một sự điều chỉnh. – guesser

1

Để trả lời câu trả lời của WWC, Jamezor nhận xét rằng mã của anh ấy sẽ thất bại nếu ký tự đầu tiên là một câu trích dẫn.

Để khắc phục vấn đề đó, bạn có thể thay thế các trường hợp StartToken với điều này:

  if (eps == enumParseState.StartToken) 
      { 
       if (rWhiteSpace.IsMatch(c.ToString())) 
       { 
        //Skip whitespace 
       } 
       else if (c == '"') 
       { 
        eps = enumParseState.InQuote; 
       } 
       else 
       { 
        token.Append(c); 
        eps = enumParseState.InToken; 
       } 
      } 
Các vấn đề liên quan