How to Embed a COM Interop DLL in a .NET Application
When you add a COM library reference in a .NET project, Visual Studio generates an interop DLL that marshals calls between managed and unmanaged code. With BoxedApp SDK, you can embed such interop assemblies directly into your executable, keeping the app self-contained and avoiding external DLLs.
What Is an Interop DLL?
When a COM library reference is added to a .NET project, a special assembly - an interop DLL - is generated. The Common Language Runtime (CLR) uses this assembly to marshal calls to the native COM methods. Sometimes it's convenient to embed these DLLs directly into your application, especially if you want to deliver a single executable.
Project Setup (Embedded Resources)
In this example, we'll use the Windows Media Player ActiveX control. When you add it to your project, Visual Studio automatically creates two interop DLLs: AxInterop.WMPLib.dll and Interop.WMPLib.dll. Add both DLLs to your project and mark them as Embedded Resources.
If you forget to mark them as embedded, GetManifestResourceStream() will fail. Here's how it should look in Visual Studio:
Initialize BoxedApp SDK
Initialize BoxedApp SDK early - before any COM objects are instantiated or assemblies loaded.
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// Initialize BoxedApp SDK
BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();Create Virtual Interop DLLs
Now create virtual files for both interop assemblies so they appear in the application directory. The code below exposes them from the embedded resources using BoxedAppSDK_CreateVirtualFile:
// Create virtual files from embedded resources
CreateFileInMemory(
Application.StartupPath + @"\AxInterop.WMPLib.dll",
Assembly.GetExecutingAssembly().GetManifestResourceStream("EmbedInteropDll.AxInterop.WMPLib.dll"));
CreateFileInMemory(
Application.StartupPath + @"\Interop.WMPLib.dll",
Assembly.GetExecutingAssembly().GetManifestResourceStream("EmbedInteropDll.Interop.WMPLib.dll"));Implementation of CreateFileInMemory
The method below creates a virtual file and writes data from an embedded resource stream to it. Handles are managed safely with SafeFileHandle to prevent leaks.
// Helper function to create a virtual file from an embedded resource
static void CreateFileInMemory(string virtualPath, Stream stream)
{
const int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
using (new SafeFileHandle(
BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFile(
virtualPath,
BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
BoxedAppSDK.NativeMethods.EFileShare.Read,
IntPtr.Zero,
BoxedAppSDK.NativeMethods.ECreationDisposition.New,
BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
IntPtr.Zero
),
true
)
)
{
}
int readBytes;
using (FileStream virtualFileStream = new FileStream(virtualPath, FileMode.Open))
{
while ((readBytes = stream.Read(buffer, 0, bufferSize)) > 0)
virtualFileStream.Write(buffer, 0, readBytes);
}
}Result
That's it! When the process requests AxInterop.WMPLib.dll or Interop.WMPLib.dll, BoxedApp SDK provides them through its virtual file system. The application works exactly as if the DLLs were on disk.