質問
コマンドライン引数を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
として取得できることです。
サポートが必要ですか
解決
チェックを実行し、問題を検証しただけです。びっくりしましたが、最初の引数の最後の\です。
"C:\Program Files\Application name\" <== remove the last '\'
これにはさらに説明が必要です。誰か考えがありますか?私はそれをバグと呼んでいます。
パート2、さらにいくつかのテストを実行して
"X:\\aa aa\\" "X:\\aa aa\" next
なる
X:\\aa aa\
X:\\aa aa" next
小さなGoogleアクションにより、 Jon Gallowayのブログでは、基本的なルールは次のとおりです。
- バックスラッシュはエスケープ文字です
- 常に引用符をエスケープします
- 引用符の前にあるバックスラッシュのみをエスケープします。
他のヒント
Ian Kempの回答を追加するには
アセンブリが<!> quot; myProg.exe <!> quotと呼ばれる場合;文字列<!> quot; C:\ Documents and Settings \ All Users \ Start Menu \ Programs \ App name <!> quot;を渡します。リンクする
C:\>myprog.exe "C:\Documents and Settings\All Users\Start Menu\Programs\App name"
文字列<!> quot; C:\ Documents and Settings \ All Users \ Start Menu \ Programs \ App name <!> quot;
args [0]になります。
他の皆がすでに言ったことに追加するために、それは逃げる問題かもしれません。別のバックスラッシュでバックスラッシュをエスケープする必要があります。
次のようになります。
C:\ <!> gt; myprog.exe <!> quot; C:\\ Documents and Settings \\ All Users \\ Start Menu \\ Programs \\ App name <!> quot;
最近、同じ厄介な問題に気づき、自分でコマンドライン引数配列を解析するパーサーを書くことにしました。
注:問題は、静的void Main(string [] args)関数に渡された.NET CommandLine引数が\ <!> quotをエスケープすることです。および\\。実際には、引用符またはバックスラッシュを含む引数を渡したい場合があるため、これは設計によるものです。一例:
次を単一の引数として渡したい場合:
-msg:ちょっと、<!> quot;どこにいるの?<!> quot;
eg。
sampleapp -msg:<!> quot;ちょっと、\ <!> quot;どこ at?\ <!> quot; <!> quot;
デフォルトの動作で送信する方法になります。
プログラムの引用符やバックスラッシュをエスケープする必要がある理由がわからない場合は、以下のように独自のパーサーを使用してコマンドラインを解析できます。
IE。 [プログラム] .exe <!> quot; C:\ test \ <!> quot; arg1 arg2
args [0] = c:\ test <!> quot; 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;
}
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;
}
}
問題は正確に何ですか?とにかくここにいくつかの一般的なアドバイスがあります:
Mainメソッド(Program.cs内)が次のように定義されていることを確認します
void Main(string[] args)
そしてargsはコマンドライン引数を含む配列です。