RoyalApps.Community.ExternalApps contains projects/packages to easily embed/use other external applications in an application.
The ExternalAppHost control starts the configured process and embeds the application window into the control.
Warning
What this control does is not exactly a Microsoft supported scenario! Please read Raymond Chen's blog post 'Is it legal to have a cross-process parent/child or owner/owned window relationship?' for more details. Spoiler alert: Yes, it's technically legal. It's also technically legal to juggle chainsaws!
You should install the RoyalApps.Community.ExternalApps.WinForms with NuGet:
Install-Package RoyalApps.Community.ExternalApps.WinForms
or via the command line interface:
dotnet add package RoyalApps.Community.ExternalApps.WinForms
Place the ExternalAppHost
on a form or in a container control (user control, tab control, etc.) and set the Dock
property to DockStyle.Fill
Create an instance of the ExternalAppConfiguration
class and set the Executable
property to the full path and file name of the application you want to embed.
Simply call:
ExternalAppHost.Start(externalAppConfiguration);
to start and embed the application.
To close the application, call:
ExternalAppHost.CloseApplication();
Depending on the application, you may get a confirmation dialog in case there are unsaved changes. You can set the ExternalAppConfiguration.KillOnClose
property to true
to forcibly quit the application by killing the process.
Note
All processes which are started by the control will be closed/killed when the main application is closed or killed.
Once the application is started and embedded, you can detach the application window by calling:
ExternalAppHost.DetachApplication();
To re-embed a detached application window, simply call:
ExternalAppHost.EmbedApplication();
Shows the app's system menu on the specified location:
ExternalAppHost.ShowSystemMenu(Point location);
ExternalAppHost.ApplicationStarted
is raised when the application has been started and embedded.ExternalAppHost.ApplicationClosed
is raised when the application was closed or killed (even outside of the hosting application).ExternalAppHost.ApplicationActivated
is raised when the application has been activated (received the input focus).ExternalAppHost.WindowTitleChanged
is raised when the window title of application window has changed.
The demo application is quite simple. It has two tab controls (one left and one right) and a bottom panel for log output. Use the toolbar to enter an executable to embed. The Add drop down allows you to choose the left or the right tab control.
There are two embed-methods available:
- Embed as Control: Only the client area of the external app window is embedded (without the main menu). The limitation of this method is that some applications may look like they are not focused/active.
- Embed as Window: The whole window is embedded including the main menu (if available). The limitation of this method is that the ALT-TAB order may be incorrect.
In the Application menu you can detach and re-embed the active external application.
This project includes a dll called WinEmbed.dll (in the /lib folder) which handles most of the Windows native stuff. You can find the C/C++ code in the /src/WinEmbed directory. To build this dll from source, you need Visual Studio 2022 or later and also the WDK installed.
For the ARM64 build to compile, install the following tools using Visual Studio 2022 installer:
MSVC v143 - VS 2022 C++ ARM64 build tools (latest)
Special thanks to Alex for helping out with all the native code challenges.