How to embed dll from "class project" into my project in vb.net
Asked Answered
F

2

7

I have a standard "class library" project with a set of classes that I use to import in almost all my new projects.

The way I work is creating a new Solution with an empty project, which is my main project, and then I add to the solution the mentioned class library project, this way I can see both projects in the Soluction Explorer and even see the library code or update it if needed. Then I write the code in my main project and I compile.

This lead me to have 2 files when I compile: file *.exe and stdlib.dll

Some cases I use the lib for very small tools that I want to redistribute in a easy and clean why, so I would like to embed the stdlib.dll generated from my class library project into my *.exe file.

I'm pretty sure there must be a why to do this in my Microsoft Visual Basic 2010 Express but I don't know how.

Any Suggestion?

Fromenty answered 5/4, 2012 at 8:28 Comment(1)
#27892050 it works same with vb.netCommoner
E
16

Here is a more 'step-by-step' version of Alex's procedure to embedding the assembly.

  1. Add the desired assembly (stdlib.dll) to the project's resources.
    Go to the Resources tab of the Project Properties and choose Add Resource > Add Existing File...
  2. Switch to the Application tab and click on the View Application Events button.
  3. Add this code to the ApplicationEvents.vb code that opens.

    Private Sub AppStart(ByVal sender As Object, 
      ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
        AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf ResolveAssemblies
    End Sub
    
    Private Function ResolveAssemblies(sender As Object, e As System.ResolveEventArgs) As Reflection.Assembly
        Dim desiredAssembly = New Reflection.AssemblyName(e.Name)
    
        If desiredAssembly.Name = "the name of your assembly" Then
            Return Reflection.Assembly.Load(My.Resources.STDLIB) 'replace with your assembly's resource name
        Else
            Return Nothing
        End If
    End Function 
    
  4. Now compile your project and you'll have the dependent assembly incorporated into the output as a single file.

Note that sometimes you may have the dependent assembly in the output folder. This is because VS is preconfigured to copy all dependent assemblies to the output path. You can override this by going to the References tab of the project's properties and then set the Copy Local property of the dependent assembly to False. This will stop the assembly from being copied to the output directory.

Ephemera answered 20/4, 2012 at 20:39 Comment(4)
Potentially stupid question: why doesn't selecting Embedded Resource in the Build Option do this for you? Put another way: why is any code required?Cascarilla
@MauryMarkowitz: The only reason I can think of is... Because this is how it works. Consider this... the .NET framework does a lot of work loading assemblies if you leave them as DLL files in the EXE path or some other standard path. If you however decide to Embedded Resource it, the framework has no way of knowing whether the resource is an assembly you want to load at run time or it is something you want to work with in any other way. It therefore relies on you to tell it where the desired assembly is and hence the need to write all this code.Ephemera
A small note for those wondering: Replace "the name of your assembly" with the exact name of the Assembly, as you would type in code. If the name is Microsoft.WindowsAPICodePack, then the value of the string will be "Microsoft.WindowsAPICodePack".Coxcombry
@AlexEssilfie Hmm. I wish Microsoft implemented a simpler solution in VS itself, or something similar.Coxcombry
F
3

You can embedd your Assembly (.dll in your case) into your project by selecting "Add existing file" and then change the Build Option to "Embedded Ressource".

You then add a Handler for the AppDomain.CurrentDomain.AssemblyResolve event which gets fired as soon as you first access the library inside your code.

That handler code looks like this: (Notice the fully qualified assembly path inclusive correct namespacs. I'd wrap it in a function which gets called on startup of your application.

   AddHandler AppDomain.CurrentDomain.AssemblyResolve,
            Function(sender As Object, args As System.ResolveEventArgs) As System.Reflection.Assembly
                Dim ressourceName = "YourNamespace.YourSubNamespace." + New AssemblyName(args.Name).Name + ".dll"
                Using stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ressourceName)
                    Dim assemblyData(CInt(stream.Length)) As Byte
                    stream.Read(assemblyData, 0, assemblyData.Length)
                    Return Assembly.Load(assemblyData)
                End Using
            End Function

You can then deploy your tool without any additional files.

Fromenty answered 5/4, 2012 at 8:52 Comment(1)
It looks more "trickier" than I thought, but thanks anyway. I'll give it a try.Fromenty

© 2022 - 2024 — McMap. All rights reserved.