What is the interop dll?

If a COM library reference is added to a .Net project, a special assembly - interop dll - is created.

With the help of the assembly CLR marshalls calls to COM methods.

Sometimes it's handy to embed interop DLL into an executable file. Let's look how to do it with BoxedApp SDK.

You can download the sample from GitHub.

BoxedApp SDK to the rescue

As BoxedApp SDK can create pseudofiles, a developer just creates virtual file of the interop DLL and the application works as expected even if real file of the interop DLL doesn't exist.

The sample

In this sample we use the Windows Media Player ActiveX. Let's add the control to the project. As you see two interop DLLs, AxInterop.WMPLib.dll and Interop.WMPLib.dll, are added to References:

Now the task is to virtualize these two DLLs. For that we need to get data for the files somewhere. The easiest way is just to add the file to the project and mark them as Embedded Resources.

Important: Mark Files as Embedded Resources.

After adding the file to embed, go to their properties and set Build Action as "Embedded Resources".

If you don't do it, GetManifestResourceStream() fails.

Look how to do it in Visual Studio:


Let's go to the code! First thing you need to do when BoxedApp SDK in the game is BoxedApp SDK initialization:

/// 
/// The main entry point for the application.
/// 
[STAThread]
static void Main()
{
    // First of all initialize BoxedApp SDK
    BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();
			

Then create virtual files of the interop DLLs. Then should be located at the application directory, that's why we use Application.StartupPath:

// Create virtual files using the data of 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"));
			

The method CreateFileInMemory creates a virtual file using the data from embedded resources.

Firstly it creates a virtual file calling BoxedAppSDK_CreateVirtualFile. This method returns virtual file handle. Close it immediately, you don't need it now. SafeFileHandle from Microsoft.Win32.SafeHandles helps.

Then just copies the data from embedded resource to virtual file:

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

That's all! Once the process asks for AxInterop.WMPLib.dll or Interop.WMPLib.dll, they are provided by BoxedApp virtualization.

Download

Sources are available on GitHub.