unity发布exe嵌入WPF(鼠标键盘可用)
Visual Studio 版本
2019
操作系统
Windows10
一. 新建WPF项目
打开VS新建项目
新建好以后,想要将unity发布的exe嵌入到WPF,并且鼠标键盘可用的话,需要在WPF项目中使用winform的UserControl控件作为载体,所以需要引用下图两个DLL。如果WindowsFormsIntegration.dll不能引用,请看文章:如何在WPF中引用Windows.System.Forms.Integration
二. 在WPF中的.xaml文件中添加以下内容
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
< WindowsFormsHost Margin = " 67,0,0,0" Grid.RowSpan = " 2" >
< wf: Panel x: Name= " host" />
</ WindowsFormsHost>
三. 将unity的exe程序嵌入到winform控件中
添加一个实体类。造函数会把WinForm控件以参数的形式传入,然后此控件需要订阅Resize事件,该事件处理器进行了exe窗体的重新激活
public class AppContainer
{
private System. Windows. Forms. Panel _hostPanel;
private readonly ManualResetEvent _eventDone = new ManualResetEvent ( false ) ;
private Process _process = null ;
internal IntPtr _embededWindowHandle;
public AppContainer ( System. Windows. Forms. Panel panel)
{
this . _hostPanel = panel;
this . _hostPanel. Resize += _hostPanel_Resize;
}
private void _hostPanel_Resize ( object sender, EventArgs e)
{
SetBounds ( ) ;
}
public void ActivateWindow ( )
{
if ( _process == null )
return ;
if ( _process. MainWindowHandle == IntPtr. Zero)
return ;
Win32Api. SendMessage ( _process. MainWindowHandle, Win32Api. WM_ACTIVATE, Win32Api. WA_ACTIVE, IntPtr. Zero) ;
}
public void SetBounds ( )
{
SetBounds ( _hostPanel. Width, _hostPanel. Height) ;
}
public void SetBounds ( int width, int height)
{
if ( _process == null )
return ;
if ( _process. MainWindowHandle == IntPtr. Zero)
return ;
if ( width <= 0 || height <= 0 )
return ;
Win32Api. MoveWindow ( _process. MainWindowHandle, 0 , 0 , width, height, true ) ;
ActivateWindow ( ) ;
}
public bool StartAndEmbedProcess ( string processPath)
{
if ( null != _process)
return true ;
var isStartAndEmbedSuccess = false ;
_eventDone. Reset ( ) ;
ProcessStartInfo info = new ProcessStartInfo ( processPath) ;
info. WindowStyle = ProcessWindowStyle. Maximized;
info. Arguments = $"-popupwindow" ;
_process = Process. Start ( info) ;
if ( _process == null )
{
return false ;
}
_process. WaitForInputIdle ( ) ;
var thread = new Thread ( ( ) =>
{
while ( true )
{
if ( _process. MainWindowHandle != ( IntPtr) 0 )
{
_eventDone.