Process.Start() and the Process Tree

前端 未结 5 1487
礼貌的吻别
礼貌的吻别 2020-12-11 02:59

How can I use Process.Start(), but have the launched process not in the same process tree as the launching process?

Consider this sample console application:

5条回答
  •  南笙
    南笙 (楼主)
    2020-12-11 03:55

    I don't believe Windows exposes (via .NET or otherwise) any method of changing a process's parent.

    As an alternative, you could run a separate process at system startup (via the "SOFTWARE/Microsoft/Windows/CurrentVersion/Run" registry key for example), and have the triggering application (your screen saver) use inter-process communication (SendMessage or the like) to tell the separate process to launch the browser. Then the separate process would be the parent and the browser wouldn't be killed when the screen saver's process tree is killed.


    Here's some example code. Note that this doesn't do any error checking, and I haven't tested it in the context of an actual screen saver, but it should give you an idea of what's involved:

    In the screen saver class:

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint RegisterWindowMessage(string lpString);
    
    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam);   
    
    private uint message;
    

    In the screen saver's initialization code:

    message = RegisterWindowMessage("LaunchBrowser");
    

    In the screen saver's browser launching code:

    SendMessage(FindWindow(null, "BrowserLauncher"), message, UIntPtr.Zero, IntPtr.Zero);
    

    In the separate process's form class:

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint RegisterWindowMessage(string lpString);
    
    private uint message;
    

    In the separate process's Form_Load code:

    message = RegisterWindowMessage("LaunchBrowser");
    Text = "BrowserLauncher";
    

    And override the separate process's form's WndProc:

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == message)
        {
            Process.Start("iexplore.exe", "http://www.google.com");
        }
    
        base.WndProc(ref m);
    }
    

    (You'll want to make the separate process's form hidden, of course.)

提交回复
热议问题