zoukankan      html  css  js  c++  java
  • 卸载程序集

    卸载程序集

    2015-04-16

    Assembly没有Unload方法,那么程序如何在运行状态下卸载程序集呢?

    可以用AppDomain.Unload方法。

    想法一 (失败):

    1. create new Domain
    2. load assembly in new domain
    3. unload the new Domain

    代码如下:

     1 using System;
     2 
     3 using System.Reflection;
     4 
     5 namespace UnloadAssembly
     6 {
     7     class Program
     8     {
     9         static void Main(string[] args)
    10         {
    11             string file1 = @"C:codeUnloadAssemblyAssembly1inDebugAssembly1.dll";
    12             AppDomain appD = AppDomain.CreateDomain("#D1"); 
    13             AssemblyName myAssemblyName1 = AssemblyName.GetAssemblyName(file1);
    14             System.IO.File.Copy(file1, GetDestinateFile(file1), true);
    15             appD.Load(myAssemblyName1);
    16             string dName = appD.FriendlyName;
    17             AppDomain.Unload(appD);
    18         }
    19 
    20         public static string GetDestinateFile(string file)
    21         {
    22             return Environment.CurrentDirectory + @"" + new System.IO.FileInfo(file).Name;
    23         }
    24     }
    25 }
    View Code

    图1 想法一

    想法二 [1](成功):

    Create a class say class "B" derived by MarshalByRefObject

    • Write a method LoadAssembly({AssemblyPath}) in class "B". This function will only load that assembly and return void.
    • Write another method ExecuteMethod({ClassName, MethodName, Params}) in class "B" . This function execute the method (name passed in the parameter) of the loaded assembly.

    Create a new class say class "A". This will be our main class from where we will start and execute the code.

    • write a main method in class "A" which will load class "B" in the new appdomain, and then call class B methods to load the assembly by passing the loadassembly method by passing assembly path and then by calling ExecuteMethod by passing method name and parameters.

     代码如下:

     1 using System;
     2 using System.Reflection;
     3 
     4 namespace UnloadAssembly
     5 {
     6     class Program
     7     {
     8         static void Main(string[] args)
     9         {
    10             string file1 = @"C:codeUnloadAssemblyAssembly1inDebugAssembly1.dll";
    11             //Creating a new appdomain 
    12             AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
    13             //Create an instance of loader class in new appdomain 
    14             AppDomain newDomain = AppDomain.CreateDomain("newDomain", AppDomain.CurrentDomain.Evidence, setup);
    15 
    16             System.Runtime.Remoting.ObjectHandle obj = newDomain.CreateInstance(typeof(LoadMyAssembly).Assembly.FullName, typeof(LoadMyAssembly).FullName);
    17 
    18             //As the object we are creating is from another appdomain hence we will get that object in wrapped format and hence in next step we have unwrappped it 
    19             LoadMyAssembly loader = (LoadMyAssembly)obj.Unwrap();
    20 
    21             //Call loadassembly method so that the assembly will be loaded into the new appdomain amd the object will also remain in new appdomain only. 
    22             loader.LoadAssembly(file1);
    23 
    24             //Call exceuteMethod and pass the name of the method from assembly and the parameters. 
    25             loader.ExecuteStaticMethod("MyClass", "MyMethod", new object[] { 1 });
    26 
    27             //After the method has been executed call unload method of the appdomain. 
    28             AppDomain.Unload(newDomain); 
    29         }
    30 
    31         public sealed class LoadMyAssembly : MarshalByRefObject
    32         {
    33             private Assembly _assembly;
    34             System.Type MyType = null;
    35             object inst = null;
    36             public override object InitializeLifetimeService()
    37             {
    38                 return null;
    39             }
    40 
    41             public void LoadAssembly(string path)
    42             {
    43                 _assembly = Assembly.Load(AssemblyName.GetAssemblyName(path));
    44             }
    45 
    46             public object ExecuteStaticMethod(string className, string methodName, params object[] parameters)
    47             {
    48                 foreach (System.Type type in _assembly.GetTypes())
    49                 {
    50                     if (String.Compare(type.Name, className, true) == 0)
    51                     {
    52                         MyType = type;
    53                         inst = _assembly.CreateInstance(type.FullName);
    54 
    55                         break;
    56                     }
    57                 }
    58                 MethodInfo MyMethod = MyType.GetMethod(methodName, new Type[] { typeof(int) });
    59                 MyMethod.Invoke(inst, BindingFlags.InvokeMethod, null, parameters, null);
    60                 return null;
    61             }
    62         }
    63 
    64         public static string GetDestinateFile(string file)
    65         {
    66             return Environment.CurrentDirectory + @"" + new System.IO.FileInfo(file).Name;
    67         }
    68     }
    69 }
    View Code

    被加载的assembly代码如下:

    1     public class MyClass
    2     {
    3         public string MyMethod(int i)
    4         {
    5             return (i * 2).ToString();
    6         }
    7     }
    View Code

    参考

    [1] How to Unload an Assembly Loaded Dynamically Using Reflection

  • 相关阅读:
    项目编译
    sqlserver查列名
    list<>初始化赋值两种方式
    看到一句很不错的话
    typescript
    vscode里div等html标签代码补全
    JavaScript 基于原型链的继承
    大数据系列01:大数据离线计算平台hadoop集群搭建和本地环境配置实践
    java数据类型
    计算机基础及java基础
  • 原文地址:https://www.cnblogs.com/Ming8006/p/4432831.html
Copyright © 2011-2022 走看看