2009-05-22 6 views
21

Come è possibile analizzare gli argomenti della riga di comando che devono essere interpretati come percorsi? args [] contiene le stringhe che sono uniti automaticamente se sono quotate, ad esempio:C# Analisi riga di comando dei percorsi citati ed eliminazione dei caratteri di escape

example.exe uno due "tre quattro"

args[0] = one 
args[1] = two 
args[2] = three four 

Tuttavia, args [] non sarà proprietà parse "C: \ Esempio \ "come argomento Piuttosto, fornirà l'argomento come "C: \ Example" "(con la citazione extra inclusa). Ciò è dovuto al backslash nel percorso trattato come carattere di escape e quindi alla citazione finale fornita dall'utente sul comando -line entra a far parte della discussione

.EG:.

uno example.exe "C: \ InputFolder" "C: \ OutuptFolder \"

args[0] = one 
args[1] = C:\InputFolder" 
args[2] = C:\OutputFolder" 

potrebbe essere un ripiego facile:

_path = args[i].Replace("\"", @"\"); 

Tuttavia, sono sicuro che ci sia una best practice per questo. Come si può analizzare correttamente una riga di comando che include percorsi, impedendo all'array args [] di essere compilato in modo errato con punture che sono state analizzate per i caratteri di escape?

NOTA: Non vorrei includere un'intera libreria di analisi della riga di comando nel mio progetto! Ho solo bisogno di gestire percorsi quotati e desidero farlo in modo "manuale". Si prega di non raccomandare NConsoler, Mono, o qualsiasi altra grande libreria di analisi della riga di comando "kitchen sink".

ANCHE NOTA: per quanto posso dire, questa non è una domanda doppia. Mentre altre domande si concentrano sull'analisi generica della riga di comando, questa domanda è specifica del problema che i percorsi introducono quando parti di esse vengono interpretate come sequenze di escape.

+0

Dove vedi esattamente questo personaggio in più? Sto usando il compilatore snippet. Ecco il principale .. string s = args [0]; \t \t Console.WriteLine (s); E funziona come dovrebbe – shahkalpesh

+0

@shahkalpesh: Non so sul tuo compilatore di snippet, ma prova a eseguirlo dalla riga di comando e fornisci al tuo programma un argomento che termina in \ "(backslash-doublequote.) Come disse ebwi, aprii gli occhi –

+0

Ho capito. Scusa se non ho capito correttamente l'argomento di input – shahkalpesh

risposta

8

Non una risposta, ma ecco qualche background and explanation da Jeffrey Tan, Microsoft Support Community Online (12/7/2006):

Nota: questo non è non è una sconfitta codice ma dal design, dal backslashe sono normalmente utilizzati per sfuggire a determinati caratteri speciali . Inoltre, questo algoritmo è lo stesso del comando Win32 argomenti di riga funzione di parsing CommandLineToArgvW. Vedi le Osservazioni sezione indicati http://msdn2.microsoft.com/en-us/library/bb776391.aspx

fa anche riferimento al metodo FX Environment.GetCommandLineArgs per ulteriori spiegazioni del comportamento movimentazione barra.

Personalmente penso che questo sia un trascinamento, e sono sorpreso che non ne sia stato morso prima. O forse ho e non lo so? Tuttavia, la sostituzione cieca delle virgolette con le barre non mi sembra una soluzione. Sto votando la domanda, perché è stata una rivelazione.

1

Mi piace la tua idea:

_path = args[i].Replace("\"", @"\"); 

È pulito, e non avrà alcun effetto a meno che non esista il problema.

+0

Ma questo non funzionerà se si dispone di: esempio.exe uno "C: \ InputFolder \" "C: \ OutuptFolder \" poiché i due percorsi verranno concatenati come arg [1] = C: \ InputFolder "C: \ Outpurfolder" –

1

Ho avuto la stessa frustrazione.La mia soluzione era usare espressioni regolari. Il mio input previsto è un elenco di percorsi, alcuni dei quali possono essere citati. Il kludge precedente non funziona a meno che non vengano citati tutti gli ultimi argomenti.

// Capture quoted string or non-quoted strings followed by whitespace 
string exp = @"^(?:""([^""]*)""\s*|([^""\s]+)\s*)+"; 
Match m = Regex.Match(Environment.CommandLine, exp); 

// Expect three Groups 
// group[0] = entire match 
// group[1] = matches from left capturing group 
// group[2] = matches from right capturing group 
if (m.Groups.Count < 3) 
    throw new ArgumentException("A minimum of 2 arguments are required for this program"); 

// Sort the captures by their original postion 
var captures = m.Groups[1].Captures.Cast<Capture>().Concat(
       m.Groups[2].Captures.Cast<Capture>()). 
       OrderBy(x => x.Index). 
       ToArray(); 

// captures[0] is the executable file 
if (captures.Length < 3) 
    throw new ArgumentException("A minimum of 2 arguments are required for this program"); 

Qualcuno può vedere una regex più efficiente?

Problemi correlati