WPF 单例应用程序

通常,WPF程序可以加载任意多个(每运行.exe一次加载一个)。有时候需要单例运行,如Word,不管打开多少个文档,只有一个应用运行。WPF没有提供单例的自带解决方案,但是可以有多种方式实现。

1.检测进程名字,进程中有名字一样的进程就不再启动。

2.Mutex  对象  (功能有限)

3.用VB 应用程序的基类对WPF 应用程序进行封装(Windows窗体为VB提供了单例的内置支持)。这种情况下,当启动应用程序时,将创建VB Application类,VB Application类接着创建WPF Application类,VB Application类负责实例的管理,实现单例,WPF Application类才是真正的应用程序。这是WPF团队的推荐做法。

方案1.  在App.xaml.cs文件中重写OnStartup方法

protected override void OnStartup(StartupEventArgs e)
{
//1 WPF单例程序:方案1,检测进程名字,名字一样就不再启动。
 Process p = Process.GetCurrentProcess();
//if (Process.GetProcessesByName(p.ProcessName).Count() > 1) GetProcessesByName返回的是数组Process[]
if(Process.GetProcessesByName(p.ProcessName).Length>1) //调试状态下的ProcessName和打包后exe运行的进程名不一样,多了后缀.vshost
{
 MessageBox.Show("Application is already run!");
 this.Shutdown();//如果缺少此句代码,即使在后加一句return也会有问题:第一次启动没问题,第二次启动提示已有运行的程序。但是当关掉第一个实例之后,便无法启动(提示已有运行的程序),因为后台还会运行Application的实例。
}

//以下跟单例无关,设置了初始化的显示界面,创建了程序的主窗体

SplashScreen ss = new SplashScreen("Pic\\t014a6628f309b37a93.jpg");
ss.Show(true);
ss.Close(new TimeSpan(0,0,10));
base.OnStartup(e);
MainWindow window = new MainWindow();
window.DataContext = new MainViewModel();
//UnsavedData = true;
// MessageBox.Show(p.Id.ToString());
window.Show();

}

  

方案2.同样是在App.xaml.cs文件中重写OnStartup方法

protected override void OnStartup(StartupEventArgs e)
{

//2 WPF单例程序:方案2,Mutex类
 bool createNew;
 Mutex mutex = new Mutex(true, p.ProcessName, out createNew);
 if(!createNew)
 {
 MessageBox.Show("Application is already run!");
this.Shutdown(); 几种关闭当前应用程序的方法
// p.Kill(); 
// Environment.FailFast("SingleInstance Already run,shutdown the second one.");
//Environment.Exit(0);
 }

}

  

 

方案3.

创建用Vb Application 封装Wpf 的类

public class SingleInstanceApplicationWrpper:Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
{
public SingleInstanceApplicationWrpper()
{
//1.激活单例标志开关
this.IsSingleInstance = true;
}

private App app;

protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs eventArgs)
{
//2.在WindowsFormsApplication的派生类中启动wpf 应用程序
app = new App();
app.Run();
return false;

//return base.OnStartup(eventArgs);

}

protected override void OnStartupNextInstance(Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs eventArgs)
{
//3.如果有已启动程序,直接调用激活主窗体
base.OnStartupNextInstance(eventArgs);
app.Active();
}

}

  

然后 定义程序的入口

public class StartUp
{
//4.主程序入口,实例化win form 的包装器,运行(要将项目中应用程序的启动对象设置为此StartUp类,否则提示多入口)
[STAThread]
public static void Main(string[] args)
{
SingleInstanceApplicationWrpper wrapper = new SingleInstanceApplicationWrpper();
wrapper.Run(args);
}
}

  再在项目-》属性-》应用程序-》启动对象中设置为StartUp

最后编译,多次执行.exe ,只会有一个程序运行。

 

posted @ 2017-12-09 11:35  大龄程序猿  阅读(695)  评论(0编辑  收藏  举报