Sample for Multi-process C# app like Google Chrome

前端 未结 2 1211
谎友^
谎友^ 2020-12-30 12:41

Is Any body knows good sample for Multi-process C# app like Google Chrome.

Thanks for help.

2条回答
  •  自闭症患者
    2020-12-30 13:11

    Took me sooo long to get all the pieces put together, but here it is:

    The XAML:

    
        
            
                
                
            
            
                

    The code-behind

    // add references to 
    // System.Windows.Forms (C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\System.Windows.Forms.dll)
    // WindowsFormsIntegration (C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\WindowsFormsIntegration.dll)
    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Windows;
    
    namespace ProcessHoster
    {
        public partial class MainWindow : Window
        {
            [DllImport("user32.dll")]
            private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
            [DllImport("user32.dll")]
            static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
            [DllImport("user32.dll")]
            public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
            [DllImport("user32.dll", SetLastError = true)]
            internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    
            enum WindowLongFlags : int
            {
                GWL_STYLE = -16,
            }
    
            enum WindowStyles : uint
            {
                WS_CHILD = 0x40000000,
                WS_BORDER = 0x00800000,
                WS_DLGFRAME = 0x00400000,
                WS_THICKFRAME = 0x00040000,
                WS_CAPTION = WS_BORDER | WS_DLGFRAME,
            }
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                string exeName = Environment.GetCommandLineArgs()[1];
                var procInfo = new ProcessStartInfo(exeName);
                procInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(exeName);
                childProcess = Process.Start(procInfo);
                childProcess.EnableRaisingEvents = true;
                childProcess.Exited += (sndr, args) => Debug.WriteLine($"Process {((Process)sndr).Id.ToString()} Exited");
                while (childProcess.MainWindowHandle == IntPtr.Zero) { Thread.Yield(); }
                var style = GetWindowLong(childProcess.MainWindowHandle, (int)WindowLongFlags.GWL_STYLE);
                style &= ~(int)WindowStyles.WS_CAPTION & ~(int)WindowStyles.WS_THICKFRAME;
                style |= ((int)WindowStyles.WS_CHILD);
                SetWindowLong(childProcess.MainWindowHandle, (int)WindowLongFlags.GWL_STYLE, Convert.ToUInt32(style));
                while (SetParent(childProcess.MainWindowHandle, hostPanel.Handle) == IntPtr.Zero) { Thread.Yield(); }
                hostPanel_Resize(null, null);
            }
    
            Process childProcess;
    
            private void hostPanel_Resize(object sender, EventArgs e)
            {
                if (childProcess?.MainWindowHandle != null)
                    MoveWindow(childProcess.MainWindowHandle, 0, 0, hostPanel.Width, hostPanel.Height, true);
            }
        }
    }
    

    Launch it with the name of the EXE you want to host, for example:

    ProcessHoster.exe "C:\Windows\System32\notepad.exe"

提交回复
热议问题