WPF Single Instance Uygulama Yapmak
26-12-2014
Yapmış olduğumuz WPF uygulamasının birden fazla kopyasını aynı anda çalıştırabiliriz. Fakat bazı durumlarda birden fazla çalışması doğru olmaz. Örneğin document tabanlı uygulamanın tek kopyasının çalışması daha mantıklı olacaktır. Buna en somut örnek Office Word uygulamasıdır. Ne kadar dosya açarsak açalım tek bir tane Office Word uygulaması çalışır. Bu tarz uygulamalara single-instance uygulamalar denir.
WPF'te single-instance uygulama yapmak biraz karmaşıktır. Bundan dolayı yapılması gereken işlem adımlarını sırasıyla inceleyelim.
Visual Basic ve Windows Form uygulamalarınının application sınıfını WPF uygulamasında kullanmamız gerekmektedir. Çünkü WPF'in application sınıfı single-instance işlemlerini halledemez. Bunun için bizim Visual Basic ve Windows Form uygulamalarında kullanılan application sınıfını kullanmamız gerekmektedir.
Bunun için ilk olarak uygulamamıza Microsoft.Visual.Basic.dll assembly eklenir ve Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase sınıfdan türeyen bir sınıf yaratılır. Bu sınıfın üç önemli üyesi bulunmaktadır:
IsSingleInstance: Bu property single-instance uygulama yapılmasını sağlar. Constructor'da bu property true yapılır.
OnStartup(): Uygulama başladığı zaman çalışır. Bu metodu override edilir ve bu metod içinde WPF application nesnesi yaratılır.
OnStartupNextInstance(): Bu metod uygulamanın bir başka instance'ı çalıştırılmaya çalışıldığı zaman tetiklenir. Bu metod komut-satırı argümanlarına erişmeyi sağlar. Bu metod ile yeni bir application nesnesi yaratılmasını engelleyebiliriz. Bunun için, yeni bir application nesnesi yaratmak yerine, var olan application nesnesinin başka bir penceresini gösterebiliriz.
Örnek:
WpfApp sınıfı
Bu sınıfları oluşturduktan sonra, uygulama çalıştırıldığı zaman App sınıfından önce, SingleInstanceApplicationWrapper sınıfının çalıştırılmasını sağlamalıyız. Bunu sağlayabilmek için de, uygulamanın App.xaml dosyasını değil, klasik Main metodu kullanılmalıdır:
WPF'te single-instance uygulama yapmak biraz karmaşıktır. Bundan dolayı yapılması gereken işlem adımlarını sırasıyla inceleyelim.
Visual Basic ve Windows Form uygulamalarınının application sınıfını WPF uygulamasında kullanmamız gerekmektedir. Çünkü WPF'in application sınıfı single-instance işlemlerini halledemez. Bunun için bizim Visual Basic ve Windows Form uygulamalarında kullanılan application sınıfını kullanmamız gerekmektedir.
Bunun için ilk olarak uygulamamıza Microsoft.Visual.Basic.dll assembly eklenir ve Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase sınıfdan türeyen bir sınıf yaratılır. Bu sınıfın üç önemli üyesi bulunmaktadır:
IsSingleInstance: Bu property single-instance uygulama yapılmasını sağlar. Constructor'da bu property true yapılır.
OnStartup(): Uygulama başladığı zaman çalışır. Bu metodu override edilir ve bu metod içinde WPF application nesnesi yaratılır.
OnStartupNextInstance(): Bu metod uygulamanın bir başka instance'ı çalıştırılmaya çalışıldığı zaman tetiklenir. Bu metod komut-satırı argümanlarına erişmeyi sağlar. Bu metod ile yeni bir application nesnesi yaratılmasını engelleyebiliriz. Bunun için, yeni bir application nesnesi yaratmak yerine, var olan application nesnesinin başka bir penceresini gösterebiliriz.
Örnek:
public class SingleInstanceApplicationWrapper : Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase { public SingleInstanceApplicationWrapper() { // Enable single-instance mode. this.IsSingleInstance = true; } // Create the WPF application class. private WpfApp app; protected override bool OnStartup( Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e) { //WpfApp sınıfı System.Windows.Application sınıfından türetilmiştir. app = new WpfApp() app.Run(); return false; } // Direct multiple instances. protected override void OnStartupNextInstance( Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e) { if (e.CommandLine.Count > 0) { app.ShowDocument(e.CommandLine[0]); } } }
WpfApp sınıfı
public class WpfApp : System.Windows.Application { protected override void OnStartup(System.Windows.StartupEventArgs e) { base.OnStartup(e); WpfApp.current = this; // Load the main window. DocumentList list = new DocumentList(); this.MainWindow = list; list.Show(); // Load the document that was specified as an argument. if (e.Args.Length > 0) ShowDocument(e.Args[0]); } public void ShowDocument(string filename) { try { Document doc = new Document(); doc.LoadFile(filename); doc.Owner = this.MainWindow; doc.Show(); // If the application is already loaded, it may not be visible. // This attempts to give focus to the new window. doc.Activate(); } catch { MessageBox.Show("Could not load document."); } } }
Bu sınıfları oluşturduktan sonra, uygulama çalıştırıldığı zaman App sınıfından önce, SingleInstanceApplicationWrapper sınıfının çalıştırılmasını sağlamalıyız. Bunu sağlayabilmek için de, uygulamanın App.xaml dosyasını değil, klasik Main metodu kullanılmalıdır:
public class Startup { [STAThread] public static void Main(string[] args) { SingleInstanceApplicationWrapper wrapper = new SingleInstanceApplicationWrapper(); wrapper.Run(args); } }