6

アプリケーションが同じ引数でそれ自体の別のコピーを再起動する正しい方法は何ですか?

私の現在の方法は、次のことを行うことです

static void Main()
{
    Console.WriteLine("Start New Copy");
    Console.ReadLine();

    string[] args = Environment.GetCommandLineArgs();

    //Will not work if using vshost, uncomment the next line to fix that issue.
    //args[0] = Regex.Replace(args[0], "\\.vshost\\.exe$", ".exe");

    //Put quotes around arguments that contain spaces.
    for (int i = 1; i < args.Length; i++)
    {
        if (args[i].Contains(' '))
            args[i] = String.Concat('"', args[i], '"');
    }

    //Combine the arguments in to one string
    string joinedArgs = string.Empty;
    if (args.Length > 1)
        joinedArgs = string.Join(" ", args, 1, args.Length - 1);

    //Start the new process
    Process.Start(args[0], joinedArgs);
}

しかし、そこには忙しい仕事がたくさんあるようです。vshost のストライピングを無視しても、スペースを含む引数をラップして"、引数の配列を 1 つの文字列に結合する必要があります。

プログラムの新しいコピー (同じ引数を含む) を起動するより良い方法はありますか?

4

3 に答える 3

3

スペースを含むコマンドライン引数を引用符で囲む必要があります (およびおそらく他の文字は、私にはわかりません)。おそらく次のようなものです:

var commandLine = string.Join(" ", args.Select(s => s.Contains(' ') ? "\"" + s + "\"" : s));
var newProcess = Process.Start("yourapplication.exe", commandLine);

さらに、使用するのではなく

string[] args = Environment.GetCommandLineArgs();

Main代わりに、メソッドでそれらを受け入れることができます。

public static void Main(string[] args)
{
    var commandLine = string.Join(" ", args.Select(s => s.Contains(' ') ? "\"" + s + "\"" : s));
    var newProcess = Process.Start(Environment.GetCommandLineArgs()[0], commandLine);
}

あなたが今持っているvshostの回避策は問題ないようですが、プロジェクトのデバッグタブで「Visual Studioホスティングプロセスを有効にする」のチェックを外して、vshost全体を無効にすることもできます。一部のデバッグ機能は、無効にすると無効になります。これについての良い説明があります

編集

これを回避するより良い方法は、コードベースをエントリ ポイント アセンブリに取得することです。

public static void Main(string[] args)
{
    var imagePath = Assembly.GetEntryAssembly().CodeBase;
    var commandLine = string.Join(" ", args.Select(s => s.Contains(' ') ? "\"" + s + "\"" : s));
    var newProcess = Process.Start(imagePath, commandLine);
}

これは、vshost が有効になっているかどうかに関係なく機能します。

于 2012-06-01T17:28:11.970 に答える
1

これでうまくいくはずです。

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern System.IntPtr GetCommandLine();
static void Main(string[] args)
{
  System.IntPtr ptr = GetCommandLine();
  string commandLine = Marshal.PtrToStringAuto(ptr); 
  string arguments = commandLine.Substring(commandLine.IndexOf("\"", 1) + 2);
  Console.WriteLine(arguments);
  Process.Start(Assembly.GetEntryAssembly().Location, arguments);
}

参考: http: //pinvoke.net/default.aspx/kernel32/GetCommandLine.html

于 2012-06-01T17:37:49.197 に答える
-1

これで十分でしょうか?

static void Main(string[] args)
{
    string commandLineArgs = args.Join(" ");
}
于 2012-06-01T17:07:42.837 に答える