适用于Google Chrome等多进程C#应用的示例

问题描述 投票:6回答:2

任何机构都知道Google Chrome等多进程C#应用程序的样本。

感谢帮助。

.net wpf winforms c#-4.0
2个回答

0
投票

花了我很长时间才把所有的东西放在一起,但这里是:

XAML:

<Window x:Class="ProcessHoster.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ProcessHoster"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel>
            <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        </StackPanel>
        <TabControl Grid.Row="1">
            <TabItem Header="Sample">
                <WindowsFormsHost x:Name="test">
                    <wf:Panel Dock="Fill" x:Name="hostPanel" AutoSize="True" Resize="hostPanel_Resize" />
                </WindowsFormsHost>
            </TabItem>
            <TabItem Header="Empty"/>
        </TabControl>
    </Grid>
</Window>

代码隐藏

// 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);
        }
    }
}

使用您要托管的EXE的名称启动它,例如:

ProcessHoster.exe“C:\ Windows \ System32 \ notepad.exe”

© www.soinside.com 2019 - 2024. All rights reserved.