1

私は小さなランチャープログラムを持っています、それはそれ自身のスレッドにスプラッシュスクリーンをロードしてそれを表示します。一連の条件が満たされた場合は、別のアプリケーションを起動し、他のアプリケーションがスプラッシュ画面を閉じても問題ないと判断するまでスプラッシュ画面を表示したままにする必要があります。

ここに画像の説明を入力してください

ランチャーには、子アプリの前に開始し、子アプリが閉じた後に終了するライフタイムが常にあります。

関連するコードのスニペットを次に示します

一般的な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();
        }
    }
}

初期ランチャー:

/// <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が作成したSplashScreenインスタンスを閉じさせる最も簡単な方法は何ですか?

4

3 に答える 3

1

これを行うには多くの方法があり、それぞれに長所と短所があります。おそらく最も簡単な方法は、ProgramLauncherプロセスからの標準出力をリダイレクトし、MicroLauncherアプリケーションのイベントに接続することです(例については、ここを参照してください)。ProgramLauncherプログラムから、特定のメッセージを標準出力に書き込みます。そのメッセージがMicroLauncherによって受信されたら、ウィンドウを閉じます。

もう1つのオプションは、スプラッシュ画面のHWNDをコマンドラインパラメーターとしてProgramLauncherに渡すことです。その後、ProgramLauncherはSendMessage(WM_SYSCOMMAND、SC_CLOSE)を使用してウィンドウを閉じることができます(例については、ここを参照してください)。

IPCの方法、カスタムWindowsメッセージの送信、またはおそらく他の1000の可能性を調べることもできますが、これら2つのアイデアで始めることができます。

于 2012-06-22T17:00:32.107 に答える
1

SplashScreenウィンドウハンドル(HWND)をに渡す必要がありますProgramLauncher。次に、winapi関数をProgramLauncher使用して、ターゲットウィンドウにメッセージを送信できます。SendMessageWM_SYSCOMMAND

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

WinFormsでは、。を使用してフォームのネイティブハンドルを取得できますHandle。プラットフォーム呼び出しコードSendMessageここにあります。

少なくとも今は簡単な方法はわかりませんが、他のIPCメカニズムよりも簡単だと思います。

于 2012-06-22T16:55:17.007 に答える
0

私が考える最も簡単な方法は、子アプリに名前付きミューテックスを作成させ、親アプリに誰かが作成するまで待機させ、時々チェックすることです。

あまりエレガントではなく、悪用される可能性があります(別のアプリが意図的に同じ名前のミューテックスを作成する場合)が、実際には、それが問題になるとは思えません。

于 2012-06-22T16:57:12.283 に答える