2013-07-21 31 views
2

作爲標題狀態,我想創建一個實例程序並在另一個實例啓動時顯示MainWindow。 我已經顯示消息,只允許一個實例。WPF,如何製作一個實例,並顯示另一個實例在c中啓動時的MainWindow。

public class MyApplication 
{ 
static Mutex mutex = new Mutex(true, "FirstInstance"); 
    [STAThread] 
    public static void Main(string[] args) 
    { 
     if (mutex.WaitOne(TimeSpan.Zero, true)) 
     { 
      App app = new App(); 
      app.InitializeComponent(); 
      app.Run(); 
     } 
     else 
     { 
      MessageBox.Show("only one instance at a time"); 
     } 
    } 
} 

這工作得很好,但我想說明主窗口,而不是一個消息,所以我

static Application app;//change app to static 
if (mutex.WaitOne(TimeSpan.Zero, true)) 
     { 
      app = new App(); 
      app.InitializeComponent(); 
      app.Run(); 
     } 
else 
{ 
    app.MainWindow.WindowState = WindowState.Normal; 
} 

嘗試,我得到「System.NullReferenceException:對象不設置到對象的實例」 。它似乎MainWindow在應用程序(這是靜態的)是空的,我不明白爲什麼。

所以我試過這篇文章http://sanity-free.org/143/csharp_dotnet_single_instance_application.html 但是WndProc方法在WPF中不存在。

我希望你能幫助我。 謝謝!

+0

因爲首先你需要創建實例App和Mainwindow。 – ethicallogics

回答

3

我創建了一個示例WPF應用程序,只更改了App.xaml.cs文件。如果單實例窗口已經打開,該代碼就會發現,當前進程的名稱相匹配的任何過程,如果這個過程有一個窗口,顯示它:

public partial class App : Application 
{ 
    // signals to restore the window to its normal state 
    private const int SW_SHOWNORMAL = 1; 

    // create the mutex 
    private const string MUTEXNAME = "FirstInstance"; 
    private readonly Mutex _mutex = new Mutex(true, MUTEXNAME); 

    public App() 
    { 
     if (!_mutex.WaitOne(TimeSpan.Zero)) 
     { 
      ShowExistingWindow(); 
      Shutdown(); 
     } 
    } 

    [DllImport("User32.dll")] 
    private static extern bool SetForegroundWindow(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 

    // shows the window of the single-instance that is already open 
    private void ShowExistingWindow() 
    { 
     var currentProcess = Process.GetCurrentProcess(); 
     var processes = Process.GetProcessesByName(currentProcess.ProcessName); 
     foreach (var process in processes) 
     { 
      // the single-instance already open should have a MainWindowHandle 
      if (process.MainWindowHandle != IntPtr.Zero) 
      { 
       // restores the window in case it was minimized 
       ShowWindow(process.MainWindowHandle, SW_SHOWNORMAL); 

       // brings the window to the foreground 
       SetForegroundWindow(process.MainWindowHandle); 

       return; 
      } 
     } 
    } 
} 

僅供參考,這是行不通的調試模式,因爲.vshost成爲進程名稱的一部分。如果您需要它以調試模式工作,則需要遍歷所有進程而不是調用Process.GetProcessesByName。

0

如果我還沒有誤解你的問題試試這樣

[STAThread] 
    public static void Main(string[] args) 
    { 
     Task task = new Task(() => { Thread.Sleep(200); MessageBox.Show("what a marvelous engineering"); }); 
     task.Start(); 
     //If you want application not to run untill task is complete then just use wait 
     task.Wait(); 

      App app = new App(); 
      app.InitializeComponent(); 
      app.Run(); 
    } 

的東西,但是我想知道,如果你想你的C#的工作你的主窗口之前完成實例你爲什麼不只是做你的另一窩只是應用程序之前=新的App()並讓代碼順序運行。

相關問題