コマンドライン引数を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によるブログ からいくつかの洞察を与えます、基本的なルールは次のとおりです:
イアンケンプの答えを追加するには
アセンブリが「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]になります。
私は最近同じ厄介な問題に気づき、コマンドライン引数の配列を自分で解析するパーサーを書くことにしました。
注:問題は、静的void Main(string [] args)関数に渡される.NET CommandLine引数が\ "および\\をエスケープすることです。これは、実際には引用符またはその中にバックスラッシュ。
次を単一の引数として渡したいとしましょう:
-msg:ねえ、「どこにいるの?」
例えば。
sampleapp -msg: "ねえ、「どこにいるの?」
デフォルトの動作で送信する方法になります。
プログラムの引用符やバックスラッシュをエスケープする必要がある理由が見つからない場合は、以下のように独自のパーサーを使用してコマンドラインを解析できます。
IE。 [プログラム] .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;
}
他の皆がすでに言ったことに加えて、それは脱出の問題かもしれません。バックスラッシュは別のバックスラッシュでエスケープする必要があります。
次のようになります:
C:\> myprog.exe "C:\\ Documents and Settings \\ All Users \\ Start Menu \\ Programs \\ App name"
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はコマンドライン引数を含む配列です。