2012-06-22 33 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消息,或可能有一千其他的可能性,但是这两个想法可以让你开始。