2012-06-22 58 views
1

我有一個小型啓動程序,它會在它自己的線程上加載一個Splash屏幕並顯示它。如果滿足一組條件,則需要啓動另一個應用程序並保持啓動畫面可見,直到另一個應用程序聲明關閉閃屏爲止。允許子程序在父應用程序的窗體上調用Close關閉

enter image description here

啓動程序將始終有一個生命週期是兒童應用之前啓動和結束的兒童應用程序關閉後。

下面是相關的一些代碼片段

常見的DLL:

namespace Example.Common 
{ 
    public partial class SplashScreen : Form 
    { 
     public SplashScreen() 
     { 
      InitializeComponent(); 
     } 

     static SplashScreen splashScreen = null; 
     static Thread thread = null; 

     static public void ShowSplashScreen() 
     { 
      // Make sure it is only launched once. 
      if (splashScreen != null) 
       return; 

      thread = new Thread(new ThreadStart(SplashScreen.ShowForm)); 
      thread.IsBackground = true; 
      thread.SetApartmentState(ApartmentState.STA); 
      thread.Start(); 
     } 

     // A static entry point to launch SplashScreen. 
     static private void ShowForm() 
     { 
      splashScreen = new SplashScreen(); 
      Application.Run(splashScreen); 
     } 

     // A static method to close the SplashScreen 
     static public void CloseForm() 
     { 
      splashScreen.Close(); 
     } 
    } 
} 

的Inital啓動:

/// <summary> 
/// This application is a small launcher to launch the real graphical launcher. It is small and lightweight and should be rarely be updated. 
/// It will call the ProgramLauncher, the program launcher will return in it's status code the PID of the instance it launched or -1 
/// if no subsequent program was started. 
/// </summary> 
[STAThread] 
static void Main() 
{ 
    //Show the Splash screen; 
    Example.Common.SplashScreen.ShowSplashScreen(); 

    //(Snip) 

    if (rights == UserRights.None) 
    { 
     SplashScreen.CloseForm(); 
     MessageBox.Show("Your user does not have permission to connect to the server.", "Unable to logon", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     return; 
    } 
    //If the user has full desktop access, give it to them and launch a new instance of the launcher. 
    else if (rights.HasFlag(UserRights.FullDesktopAccess)) 
    { 
     Process explorer = new Process(); 
     explorer.StartInfo.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"); 
     if (explorer.Start() == false) 
     { 
      MessageBox.Show("Explorer failed to start."); 
     } 
     else 
     { 
      //Close the splash screen. 
      SplashScreen.CloseForm(); 

      //If the user can shadow start a new instance of the launcher inside explorer. 
      if (rights.HasFlag(UserRights.ShadowNormalUser) || rights.HasFlag(UserRights.ShadowDemoUser)) 
      { 
       //Start a new copy of the program so people can use it to shadow easily. 
       var shadowProc = new Process(); 
       shadowProc.StartInfo.FileName = "ProgramLauncher.exe"; 
       shadowProc.StartInfo.UseShellExecute = false; 
       shadowProc.Start(); 
      } 
      explorer.WaitForExit(); 
     } 
    } 
    else 
    { 
     Process programLauncher = new Process(); 
     programLauncher.StartInfo.FileName = "ProgramLauncher.exe"; 
     programLauncher.StartInfo.UseShellExecute = false; 

     //Launch the graphical launcher. 
     programLauncher.Start(); 
     programLauncher.WaitForExit(); 

     //Check to see if the graphical launcher launched some other process. 
     if (programLauncher.ExitCode >= 0) 
     { 
      //If there was a pid, don't close the micro launcher till after it closes. 
      Process runningProcess = Process.GetProcessById(programLauncher.ExitCode); 
      runningProcess.WaitForExit(); 
     } 

    } 
} 

是什麼讓ProgramLauncher關閉閃屏情況下的最簡單的方法MicroLauncher產生的?

+0

的這種使用情況是MicroLauncher作爲替代外殼,同時使用遠程桌面,但是當它關​​閉它註銷用戶,所以必須保持打開狀態,直到它催生了所有進程(和它的孩子們產生了過程)關閉。 –

回答

1

你需要有SplashScreen傳的窗口句柄(HWND)到ProgramLauncher。然後,ProgramLauncher可以使用SendMessage WINAPI函數來發送一個WM_SYSCOMMAND消息到目標窗口:

public const int WM_SYSCOMMAND = 0x0112; 
public const int SC_CLOSE = 0xF060; 
SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0); 

在的WinForms,你可以得到一個形式的原生手柄Handle。 平臺調用代碼SendMessagehere

至少我現在不看一個更簡單的方法,但我認爲這是比任何IPC機制在那裏更容易。我能想到的

0

最簡單的方式:將孩子的應用程序創建一個名爲互斥體,並有父應用程序等待,直到有人在創造了它,現在,然後檢查每個。

不是很優雅和開放的濫用(其中另一個應用程序創建故意用相同名稱的互斥體),但在實踐中,我懷疑這會是一個問題。

1

有很多方法可以做到這一點,每個方法都有優點和缺點。 最簡單的方法是重定向來自ProgramLauncher進程的標準輸出,並將其連接到MicroLauncher應用程序中的事件(例如參見here)。從ProgramLauncher程序中,您可以向標準輸出寫入特定消息。當MicroLauncher收到該消息時,關閉該窗口。

另一種方法是將啓動畫面的HWND作爲命令行參數傳遞給ProgramLauncher,然後ProgramLauncher可以使用SendMessage(WM_SYSCOMMAND,SC_CLOSE)關閉窗口(例如參見here)。

您還可以查看到IPC的方法,發送自定義Windows消息,或可能有一千其他的可能性,但是這兩個想法可以讓你開始。