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 ,只会有一个程序运行。