none
Unloading a dynamically loaded assembly RRS feed

  • Question

  • Okay,

    So there are moments where reflection is awesome.  Other times, like this, it can be a royal pain.

    I have a system in place which allows the user to select an assembly and load it for evaluation of exported types within. 

    However, once loaded into the current process space, regardless of the purpose, it stays there.  So in this case, the system loading the assembly is an ItemTemplate for Visual Studio.  That means, that once loaded, visual studio tends to hand on to it, for some annoying reason, regardless if my template wizard is still in memory. 

    I'd like to know if there is a way, to Load up an assembly, get the type information from it, use that type information for code generation purposes, and then UNLOAD the assembly, so that VS or any other editor is not still referencing it.

    Thanks

    Jaeden "Sifo Dyas" al'Raec Ruiner

    PS - I'm currently using Assmbly.LoadFile(), there are other avenues, but not sure which will serve my purposes of only having the assembly loaded into the 3rd party application (so to speak) for duration of that application being in memory.  ReflectionOnlyLoad(), load from a byte array, whatever.


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.

    Wednesday, October 23, 2019 11:52 PM

All replies

  • Hi JaedenRuiner,

    Thank you for posting here.

    According to your question, I have a question to confirm with you.

    >>use that type information for code generation purposes, and then UNLOAD the assembly, so that VS or any other editor is not still referencing it.

    Could you provide more descriptions about it?

    Besides, I find some references.

    1. Correct Way to Load Assembly, Find Class and Call Run() Method
    2. Best Practices for Assembly Loading
    3. Loading .NET Assemblies out of Seperate Folders

    Hope them could be helpful.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, October 24, 2019 10:00 AM
    Moderator
  • >>use that type information for code generation purposes, and then UNLOAD the assembly, so that VS or any other editor is not still referencing it.

    Could you provide more descriptions about it?

    It's not really essential to the problem at hand.  I create automation tools for generating source code that is repeatable, so as to save time.  The same concept is behind the entire VSTemplate system and Template Wizards, i just expand upon it a great deal.

    In the spirit of that, one of my generated systems is designed to operate on two classes, an object-to-object copy system that you point it at one, point it the other, map the properties, and the code is generated to transfer the data between them.

    In order to do that, i need to "Load" the individual assemblies with the Types contained.  However, once loaded they remain loaded in memory until the application terminates.  However, when being used via an editor the process space is owned by Visual Studio, so i can't release that assembly.

    I have however, looked into it more and found that by using an AppDomain I might be able to achieve what I want.

    EDIT:

    So, i've done the create domain part, and tried to use the AppDomain.Load(byte[], byte[]) method, but I'm getting a FileNotFoundExcpetion.  I tried listing to the ResolveAssembly event and the file it can find it the file that i loaded into the byte array.  So it shoudln't need a file, it should just load from the raw data i provided.  If Microsoft is going to deprecate Assembly.LoadFile() then the other methods that load from a byte[] should work without a file reference. 

    I just want to load an assembly, retrieve the Exported Types, and reference the PropertyInfo's on that type.  Period.  Why is this so damn difficult.

    Thanks

    J"SD"a'RR


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.


    • Edited by JaedenRuiner Thursday, October 24, 2019 11:29 PM
    Thursday, October 24, 2019 9:24 PM
  • Hi JaedenRuiner,

    Thanks for your feedback.

    I make a test which use Assembly.LoadFrom() method to load dll and get the PropertyInfo of the class.

    Here's the code:

                Assembly asm = Assembly.LoadFrom(@"your path of dll");
                Type t1 = asm.GetType("TestAssembly.Class1");
                PropertyInfo[] propinfo = asm.GetType("TestAssembly.Class1").GetProperties();

    My information in Class1:

    namespace TestAssembly
    {
        public class Class1
        {
            public int Property1 { get; set; }
            public string Property2 { get; set; }
            void method1()
            {
    
            }
        }
    }

    Result:

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, October 30, 2019 9:56 AM
    Moderator
  • Obviously you didn't read the problem. 

    THe problem is not LOADING the assembly, the problem is UNLOADING the assembly.

    Since the application in question, albeit a separate process, is loaded by Visual Studio when you attempt to edit the file associated with that application as an editor, once an assembly is loaded, Visual Studio retains that assembly in a lock.  Thus, if the assembly i want to load is currently being used by the current project I'm developing in VS if i do what you suggested above i can't rebuild that assembly file because it is locked.

    1. Build Solution
    2. Open editor for class that copies one type to another type
    3. Point editor at build DLL
    4. Load Assembly
    5. Map the Types in Editor
    6. Save and regenerate class that handles the copying.
    7. Build Solution
    8. Solution FAILS because it cannot access the DLL i opened in step #3
    9. Close Visual Studio
    10. Restart Visual Studio an Open Solution
    11. Build Solution (now works.)  if i use my editor to load the assembly i have to repeat #9-#11 every time i use my editor in order to rebuild the solution, because i can't UNLOAD the assembly from the editor.

    If however, there was a way for me to "UNLOAD" the assembly i loaded in #4 before i try #6 it should work.  But i can't UNLOAD an assembly from a process. 

    i want:

    Assembly asm = Assembly.LoadFrom(filePath);
    AssemblyTypesTree tree = AssemblyTypesTree.Load(asm);
    Assembly.UnLoad(asm);
    //or 
    asm.Dispose()
    

    Once the assembly is loaded into the AssemblyTypesTree, it no longer is needed in memory because the data has been converted to text which i can still use in the code generation process. Yet the system treats it like i am "referencing" that assembly when no other code touches it.  Nothing ever instantiates any of the types, or anything like that. So why can't i "read" the assembly for type information and then close it just like i can a Word document?

    I can "close" a file so another program can access it, but i can't seem to do that when using Assembly.Load()

    Thanks

    J"SD"a'RR


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.


    Friday, August 21, 2020 8:27 PM
  • Did you continue the investigations with regards to AppDomain and its Unload (and maybe ReflectionOnlyLoadFrom)?

    See:

    Saturday, August 22, 2020 8:02 AM
  • you need to load the assembly in a separate appdomain, do your reflection , then unload the appdomain to unload the assembly.
    see How to: Load and unload assemblies
    Saturday, August 22, 2020 8:03 AM