locked
Call DLL file included into the project RRS feed

  • Question

  • I can add DLL file to C# my project resources , Then I need a way to call a function in this DLL without extract it outside the exe file.
    • Edited by Tarek1500 Wednesday, March 18, 2015 5:55 PM
    Wednesday, March 18, 2015 5:50 PM

Answers

  • Is it a Win32 DLL or a .NET assembly.  If a .NET assembly you can certainly just use Assembly.Load(byte[])

    David


    David http://blogs.msdn.com/b/dbrowne/

    • Proposed as answer by Andrew B. Painter Wednesday, March 18, 2015 7:58 PM
    • Marked as answer by Kristin Xie Saturday, March 28, 2015 6:52 AM
    Wednesday, March 18, 2015 7:50 PM
  • I just tested this out, and here's a simple process that appears to work. 

    1) Change the reference to the target assembly to set "Copy Local" to False in order to prevent the assembly from being copied to your bin folder.

    2) Add a file resource to your .EXE for the library, say "ClassLibrary1".

    3) Add a pre-build step to copy the assembly to your resources folder, eg

    copy "$(SolutionDir)ClassLibrary2\bin\Debug\ClassLibrary2.dll" "$(ProjectDir)Resources"

    4) Add an AssemblyResolve event handler in your main program to load the assembly from the resource. eg

        class Program
        {
            private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
            {
                if (args.Name == "ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
                {
                    var assembly = Assembly.Load(Properties.Resources.ClassLibrary2);
                    return assembly;
                }
                return null;
            }
    
            static Program()
            {
                AppDomain.CurrentDomain.AssemblyResolve += MyResolveEventHandler;
            }

    Then you can use the referenced assembly as you normally would, with a design-time referenced assembly.

    David


    David http://blogs.msdn.com/b/dbrowne/



    Thursday, March 19, 2015 2:06 PM

All replies

  • That's really not what Resources are best used for.  Why not just reference the DLL and distribute it as part of your software package? 

    Content Removed

    Wednesday, March 18, 2015 6:24 PM
  • Just because. I need a solution to call it inside the exe file.
    Wednesday, March 18, 2015 7:46 PM
  • Is it a Win32 DLL or a .NET assembly.  If a .NET assembly you can certainly just use Assembly.Load(byte[])

    David


    David http://blogs.msdn.com/b/dbrowne/

    • Proposed as answer by Andrew B. Painter Wednesday, March 18, 2015 7:58 PM
    • Marked as answer by Kristin Xie Saturday, March 28, 2015 6:52 AM
    Wednesday, March 18, 2015 7:50 PM
  • OK good. But then how to call a function or use anything inside DLL?
    Wednesday, March 18, 2015 9:45 PM
  • I just tested this out, and here's a simple process that appears to work. 

    1) Change the reference to the target assembly to set "Copy Local" to False in order to prevent the assembly from being copied to your bin folder.

    2) Add a file resource to your .EXE for the library, say "ClassLibrary1".

    3) Add a pre-build step to copy the assembly to your resources folder, eg

    copy "$(SolutionDir)ClassLibrary2\bin\Debug\ClassLibrary2.dll" "$(ProjectDir)Resources"

    4) Add an AssemblyResolve event handler in your main program to load the assembly from the resource. eg

        class Program
        {
            private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
            {
                if (args.Name == "ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
                {
                    var assembly = Assembly.Load(Properties.Resources.ClassLibrary2);
                    return assembly;
                }
                return null;
            }
    
            static Program()
            {
                AppDomain.CurrentDomain.AssemblyResolve += MyResolveEventHandler;
            }

    Then you can use the referenced assembly as you normally would, with a design-time referenced assembly.

    David


    David http://blogs.msdn.com/b/dbrowne/



    Thursday, March 19, 2015 2:06 PM
  • "Then you can use the referenced assembly as you normally would" How?

    I use "Assembly.Load()" already

    Thursday, March 19, 2015 3:46 PM
  • >"Then you can use the referenced assembly as you normally would" How?

    By setting a reference to the library (With Copy Local=False) and then just referencing types defined in that library.  Eg

       var c = new ClassLibrary2.Class1();
       c.Foo();

    The alternative is to use reflection

       var assembly = Assembly.Load(Properties.Resources.ClassLibrary2);
       dynamic obj = assembly.CreateInstance("ClassLibrary2.Class1");
       obj.Foo();

    David


    David http://blogs.msdn.com/b/dbrowne/



    Thursday, March 19, 2015 7:07 PM
  • Doesn't work with class without constructors. It gives me this exception error

    "Constructor on type 'MyClass' not found."

    I have to call static method inside the DLL.

    And later if I add two DLL files , and the first DLL calls the second one and I don't have access to the second , First file will call Second normally from resources or must do something?

    Thursday, March 19, 2015 8:33 PM
  • I just tested this out, and here's a simple process that appears to work. 

    1) Change the reference to the target assembly to set "Copy Local" to False in order to prevent the assembly from being copied to your bin folder.

    2) Add a file resource to your .EXE for the library, say "ClassLibrary1".

    3) Add a pre-build step to copy the assembly to your resources folder, eg

    copy "$(SolutionDir)ClassLibrary2\bin\Debug\ClassLibrary2.dll" "$(ProjectDir)Resources"

    4) Add an AssemblyResolve event handler in your main program to load the assembly from the resource. eg

        class Program
        {
            private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
            {
                if (args.Name == "ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
                {
                    var assembly = Assembly.Load(Properties.Resources.ClassLibrary2);
                    return assembly;
                }
                return null;
            }
    
            static Program()
            {
                AppDomain.CurrentDomain.AssemblyResolve += MyResolveEventHandler;
            }

    Then you can use the referenced assembly as you normally would, with a design-time referenced assembly.

    David


    David http://blogs.msdn.com/b/dbrowne/



    Don't want to thread hijack, but this is of use to me as well.

    Can you output that for VB.NET David?

    I'm assuming you would use standard Reflection commands afterwards, correct?

    Thursday, March 19, 2015 8:46 PM
  • If you want to call a static method through reflection, it would be something like this:

                var type = assembly.GetType("ClassLibrary2.Class1");
                var methodInfo = type.GetMethod("Bar");
                methodInfo.Invoke(null, null);
    

    David


    David http://blogs.msdn.com/b/dbrowne/

    Thursday, March 19, 2015 9:04 PM
  • Now it gives me this exception error :D

    "Ambiguous match found."

    I think because it has overloaded methods.

    Thursday, March 19, 2015 9:09 PM
  • >Can you output that for VB.NET David?

    Something like

    Class Whatever
        Private Shared Function MyResolveEventHandler(sender As Object, args As ResolveEventArgs) As Assembly
            If args.Name = "ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Then
                Dim asm = Assembly.Load(My.Resources.ClassLibrary2)
                Return asm
            End If
            Return Nothing
        End Function
    
        Shared Sub New()
            AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf MyResolveEventHandler
        End Sub
    With help from http://converter.telerik.com/

    David


    David http://blogs.msdn.com/b/dbrowne/

    Thursday, March 19, 2015 9:11 PM