Load Ribbon DLL From Embedded Resource


Read more: http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource

In normal way, when System.Windows.Forms.Ribbon35.DLL is added as reference and build with WinForms, we'll see the assembly of System.Windows.Forms.Ribbon35.DLL is distributed together with our application. It is located as the same folder along with the main EXE application.

a01.png

If the assembly of System.Windows.Forms.Ribbon35 is missing, we'll receive an error (Exception) while executing the program:

a0.png

One of the way to resolve this is to include the assembly of System.Windows.Forms.Ribbon35.DLL as Embedded Resource. System.Windows.Forms.Ribbon35.DLL will be packed within our application. As a result, only one EXE executable application will be distributed.

And this is what will be explained in this guide.


Lets Start...


1st, as normal step of starting with Ribbon, we are going to add System.Windows.Forms.Ribbon35.DLL as reference.

a1.png

Next, Add the file - Ribbon.DLL, Right Click at the Project's Name > Add > Existing Item...

embedasm01.png

Locate System.Windows.Forms.Ribbon35.DLL...

Change the Properties of both Referenced DLL and Added File of DLL...

Referenced DLL > Change Copy Local = False

Added File DLL > Change Build Action = Embedded Resource

embedasm081.png

Open Program.cs.

embedasm05.png

Add this Using code at top:
using System.Reflection;
Initial Program.cs code:
static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
Declare a static object of an Assembly to hold the Embbed Ribbon DLL in memory:
static class Program
{
    public static Assembly ribbon = null;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
Loading the Embedded System.Windows.Forms.Ribbon.DLL into static object of Assembly (ribbon).
static class Program
{
    public static Assembly ribbon = null;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        string resource = "MyApp.System.Windows.Forms.Ribbon35.dll";
        using (Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
        {
            byte[] ba = new byte[(int)stm.Length];
            stm.Read(ba, 0, (int)stm.Length);
            ribbon = Assembly.Load(ba);
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
Take a note of the resource string. It is the combination of namespace + complete filename:

embedasm06.png

If the assembly is located inside a folder, the folder name must be included too:

embedasm07.png

During the execution time, when the application fail to locate the Ribbon DLL, it will raise the event of AppDomain.CurrentDomain.AssemblyResolve. We will load System.Windows.Forms.Ribbon35.DLL in that event during runtime.
static class Program
{
    public static Assembly ribbon = null;
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        string resource = "MyApp.System.Windows.Forms.Ribbon35.dll";
        using (Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
        {
            byte[] ba = new byte[(int)stm.Length];
            stm.Read(ba, 0, (int)stm.Length);
            ribbon = Assembly.Load(ba);
        }

        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (args.Name.StartsWith("System.Windows.Forms.Ribbon35"))
        {
            return ribbon;
        }
        return null;
    }
}

Last edited May 21, 2013 at 3:19 AM by adriancs, version 14

Comments

mrvijayk1 Feb 16, 2014 at 11:34 AM 
When I use I get an error {"Object reference not set to an instance of an object."} at byte[] ba = new byte[(int)stm.Length];

michaelmotes Sep 21, 2013 at 5:55 AM 
Why not just include the source for the control in your project?

adriancs May 21, 2013 at 3:21 AM 
using System.Reflection;

CCook5805 Feb 18, 2013 at 8:35 PM 
What "using" line is required to use the Assembly object?