How to load a .NET assembly for reflection operations and subsequently unload it?

后端 未结 5 804
青春惊慌失措
青春惊慌失措 2020-11-28 06:11

I\'m writing a tool to report information about .NET applications deployed across environments and regions within my client\'s systems.

I\'d like to read the values

相关标签:
5条回答
  • 2020-11-28 06:19

    You can try to use Unmanaged Metadata API, which is COM and can easily be used from .NET application with some kind of wrapper.

    0 讨论(0)
  • 2020-11-28 06:26

    Whilst not really about unloading assemblies, if you're just trying to get the version number of a file you can use System.Diagnostics.FileVersionInfo.

    var info = FileVersionInfo.GetVersionInfo(path);
    

    FileVersionInfo has the following properties:

    public string Comments { get; }
    public string CompanyName { get; }
    public int FileBuildPart { get; }
    public string FileDescription { get; }
    public int FileMajorPart { get; }
    public int FileMinorPart { get; }
    public string FileName { get; }
    public int FilePrivatePart { get; }
    public string FileVersion { get; }
    public string InternalName { get; }
    public bool IsDebug { get; }
    public bool IsPatched { get; }
    public bool IsPreRelease { get; }
    public bool IsPrivateBuild { get; }
    public bool IsSpecialBuild { get; }
    public string Language { get; }
    public string LegalCopyright { get; }
    public string LegalTrademarks { get; }
    public string OriginalFilename { get; }
    public string PrivateBuild { get; }
    public int ProductBuildPart { get; }
    public int ProductMajorPart { get; }
    public int ProductMinorPart { get; }
    public string ProductName { get; }
    public int ProductPrivatePart { get; }
    public string ProductVersion { get; }
    public string SpecialBuild { get; }
    
    0 讨论(0)
  • 2020-11-28 06:28

    You can create an instance in the new AppDomain and execute your code in that instance.

    var settings = new AppDomainSetup
    {
        ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
    };
    var childDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, settings);
    
     var handle = Activator.CreateInstance(childDomain,
                typeof(ReferenceLoader).Assembly.FullName,
                typeof(ReferenceLoader).FullName,
                false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, null, CultureInfo.CurrentCulture, new object[0]);
    
    
    var loader = (ReferenceLoader)handle.Unwrap();
    
    //This operation is executed in the new AppDomain
    var paths = loader.LoadReferences(assemblyPath);
    
    
    AppDomain.Unload(childDomain);
    

    Here is the ReferenceLoader

    public class ReferenceLoader : MarshalByRefObject
    {
        public string[] LoadReferences(string assemblyPath)
        {
            var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
            var paths = assembly.GetReferencedAssemblies().Select(x => x.FullName).ToArray();
            return paths;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 06:32

    You have to use application domains, there's no other way to unload an assembly. Basically you have to use code like this:

    
    AppDomain tempDomain = AppDomain.CreateDomain("Temp Domain");
    tempDomain.Load(assembly);
    AppDomain.Unload(tempDomain);
    
    
    0 讨论(0)
  • 2020-11-28 06:33

    From the MSDN documentation of System.Reflection.Assembly.ReflectionOnlyLoad (String) :

    The reflection-only context is no different from other contexts. Assemblies that are loaded into the context can be unloaded only by unloading the application domain.

    So, I am afraid the only way to unload an assembly is unloading the application domain. To create a new AppDomain and load assemblies into it:

    public void TempLoadAssembly()
    {
        AppDomain tempDomain = AppDomain.CreateDomain("TemporaryAppDomain");
        tempDomain.DoCallBack(LoaderCallback);
        AppDomain.Unload(tempDomain);
    }
    
    private void LoaderCallback()
    {
        Assembly.ReflectionOnlyLoad("YourAssembly");
        // Do your stuff here
    }
    
    0 讨论(0)
提交回复
热议问题