C# 如何创建应用程序的第二个实例?

C# 如何创建应用程序的第二个实例?,c#,wpf,C#,Wpf,我希望在启动时为通过命令行参数传递给它的每个文件路径创建我的应用程序的新实例 现在,我在主窗口的构造函数中有: if (args.Length > 0) { for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (File.Exists(arg))

我希望在启动时为通过命令行参数传递给它的每个文件路径创建我的应用程序的新实例

现在,我在主窗口的构造函数中有:

if (args.Length > 0)
        {
            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i];

                if (File.Exists(arg))
                {
                    if (i > 0)
                        Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location, arg);
                    else
                        OpenFile(arg);
                }
            }
        }
if(args.Length>0)
{
for(int i=0;i0)
Process.Start(System.Reflection.Assembly.getExecutionGassembly().Location,arg);
其他的
OpenFile(arg);
}
}
}
但是,现在我的程序似乎要创建自己的新实例,直到我的计算机运行我们的内存。你知道怎么了吗

--编辑--


Args来自appapplication.OnStartup事件的重写。

删除对
if(Args.Length>0)
的检查,因为for循环将处理该问题。如果需要跳过arg0(如SLaks所建议的),只需将for循环更改为
inti=1

请注意,如果您总是将参数传递给子进程,并且您的检查基于它们是否为任何参数,那么您将无限递归

所以这一行应该改变:

if (i > 0)
    // Spawn new process, passing the argument
致:

此外,正如这里的答案所证明的,这段代码相当混乱。下面是更简单的代码:

foreach (string arg in args.Skip(2)) // Just Skip(1) if it turns out args[0] != this.exe
    Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location, arg);

if (args.Length > 1) // > 0 if it turns out args[0] != this.exe
    OpenFile(args[1]);

取消对if(args.Length>0)的检查,因为for循环将处理该问题。如果需要跳过arg0(如SLaks所建议的),只需将for循环更改为
inti=1

请注意,如果您总是将参数传递给子进程,并且您的检查基于它们是否为任何参数,那么您将无限递归

所以这一行应该改变:

if (i > 0)
    // Spawn new process, passing the argument
致:

此外,正如这里的答案所证明的,这段代码相当混乱。下面是更简单的代码:

foreach (string arg in args.Skip(2)) // Just Skip(1) if it turns out args[0] != this.exe
    Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location, arg);

if (args.Length > 1) // > 0 if it turns out args[0] != this.exe
    OpenFile(args[1]);

如果您的目标是允许所有处理同时运行,那么为什么不使用线程呢

foreach (var i in args) {
    new Thread(delegate {
        try { OpenFile(i); }
        catch (Exception e) { Console.WriteLine("Error processing file {0}: {1}",
                                                i, e.ToString()); }
    }).Start();
}

如果您的目标是允许所有处理同时运行,那么为什么不使用线程呢

foreach (var i in args) {
    new Thread(delegate {
        try { OpenFile(i); }
        catch (Exception e) { Console.WriteLine("Error processing file {0}: {1}",
                                                i, e.ToString()); }
    }).Start();
}
换成

Process.Start(typeof(MainWindow).Assembly.Location, "\"" + arg + "\"");
(在论点周围加引号)

如果arg来自带空格的带引号的路径,则将其传递给
Process.Start
将把未带引号的值作为两个参数传递。你需要在它周围加引号,以确保你只得到一个参数

更改第一个参数将使其更短更快,但不会改变行为。

将其更改为

Process.Start(typeof(MainWindow).Assembly.Location, "\"" + arg + "\"");
(在论点周围加引号)

如果arg来自带空格的带引号的路径,则将其传递给
Process.Start
将把未带引号的值作为两个参数传递。你需要在它周围加引号,以确保你只得到一个参数

更改第一个参数会使其更短更快,但不会改变行为。

回答:我是个白痴

出于测试目的,我硬编码了一些参数,这些新实例随后生成

请随意通过你的电脑屏幕指向我笑或扔鸡蛋。

回答:我是个白痴

出于测试目的,我硬编码了一些参数,这些新实例随后生成



请随意通过您的电脑屏幕指向我笑或向我扔鸡蛋。

不,不会的。他已经在检查
i>0
。此外,这将阻止它实际打开文件。您是对的,在考虑第一个参数后,他需要检查
i>1
。我们都错了<代码>StartupEventArgs.Args不包括应用程序名称。(我检查了文件和来源)不,不会的。他已经在检查
i>0
。此外,这将阻止它实际打开文件。您是对的,在考虑第一个参数后,他需要检查
i>1
。我们都错了<代码>StartupEventArgs.Args不包括应用程序名称。(我检查了文档和源代码)多个UI线程是个坏主意。此外,这是窗口的构造函数;他需要调用
new Application().Run(new main window(…)
Ah,错过了问题中指定这是一个GUI应用程序的部分。如果他为每个UI使用appdomains,他可能能够解决这个问题,但可能会有相当多的问题。更好的办法是重构应用程序以支持多个文件/多个窗口。多个UI线程是个坏主意。此外,这是窗口的构造函数;他需要调用
new Application().Run(new main window(…)
Ah,错过了问题中指定这是一个GUI应用程序的部分。如果他为每个UI使用appdomains,他可能能够解决这个问题,但可能会有相当多的问题。更好的方法是重构应用程序以支持多个文件/多个窗口。如果在调试器中单步执行,会发生什么?它会进入Process.Start(System.Reflection.Assembly.getExecutionGassembly().Location,arg);然后不断生成越来越多的实例。如果在调试器中单步执行会发生什么情况?它将进入Process.Start(System.Reflection.Assembly.getExecutionGassembly().Location,arg);然后不断产生越来越多的实例。我怀疑这不是您当前的问题,但这肯定是您应该修复的错误。谢谢!要是你昨天发这封信时我看到就好了。我花了至少一个小时怀疑wtf是错的。我怀疑这不是你的直接问题,但这肯定是一个你应该修复的错误。谢谢!要是你昨天发这封信时我看到就好了。我花了至少一个小时怀疑wtf是错的。你仍然应该在我的(新)答案中修复不相关的错误。你仍然应该在我的(新)答案中修复不相关的错误。