日期:2014-05-20  浏览次数:20831 次

炸弹是怎样爆炸的-动态装卸DLL
我来设计一个例子,我在D目录运行程序A(土匪)。然后望D目录丢文件(炸弹)过去,土匪判断该文件是否炸弹(包含实现了接口IBomb的类),如果是,则执行IBomb的Explode方法让炸弹爆炸,当然炸了以后就没有了,文件将被删除。

   
接口定义--编译为Interface.dll供炸弹和土匪引用。
C# code
using System;
namespace Interface
{
    public interface IBomb
    {
        void Explode();
    }
}



炸弹定义--编译为ClassLibrary1.dll,准备交给土匪

C# code
using System;
namespace ClassLibrary1
{
    public class Class1:Interface.IBomb
    {
        public void Explode()
        {
            Console.WriteLine("bo~~~");
        }
    }
}



那么程序A,引爆炸弹而且能把炸弹扔掉的土匪--编译为AppDomainTest.exe

C# code
using System;
using System.Reflection;

namespace AppDomainTest
{
    /// <summary>
    /// 动态装卸dll程序集示例
    /// 这里用一个有趣的例子:
    /// 
    /// 我把一个dll看作是炸弹,执行如下操作
    /// 1、炸弹扔到程序运行目录中
    /// 2、引爆炸弹
    /// 3、炸弹消失
    /// 
    /// 
    /// </summary>
    class Program
    {
        /// <summary>
        /// 使用FileSystemWatcher监视炸弹,如果有则引爆
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("Press Any Key To Exit ...");

            System.IO.FileSystemWatcher fsWatcher = new System.IO.FileSystemWatcher();
            fsWatcher.Path =System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            fsWatcher.Filter = "*.dll";
            fsWatcher.EnableRaisingEvents = true;

            fsWatcher.Created += new System.IO.FileSystemEventHandler(fsWatcher_Created);

            Console.ReadKey();
        }

        /// <summary>
        /// 如果有炸弹丢过来则引爆
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void fsWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
        {
            InvokeExplode(e.FullPath);
        }
        /// <summary>
        /// 不能炸着自己,创建一个AppDomain...
        /// </summary>
        /// <param name="fileName"></param>
        public static void InvokeExplode(string fileName)
        {
            try
            {
                System.AppDomain app = System.AppDomain.CreateDomain(System.IO.Path.GetFileNameWithoutExtension(fileName));

                System.Runtime.Remoting.ObjectHandle objLoader=
                    app.CreateComInstanceFrom(System.Reflection.Assembly.GetExecutingAssembly().Location, "AppDomainTest.RemoteLoader");

                RemoteLoader loader = objLoader.Unwrap() as RemoteLoader;

                loader.InvokeExplode(fileName);

                System.AppDomain.Unload(app);

                System.IO.File.Delete(fileName);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
    }

    /// <summary>
    /// 在这里爆炸,注意这里的Assembly不能被外面访问
    /// </summary>
    class RemoteLoader : MarshalByRefObject
    {
        public void InvokeExplode(string fileName)
        {
            Assembly assembly = Assembly.LoadFile(fileName);
            foreach (System.Type type in assembly.GetTypes())
            {
                if (type.GetInterface(typeof(Interface.IBomb).FullName) != null)
                {
                    object obj = assembly.CreateInstance(type.FullName,true);

                    ((Interface.IBomb)obj).Explode();
                }
            }
        }
    }

     
}



--这三个文件怎么呢?第一个不能玩,是给第二个和第三个引用的。

运行AppDomainTest.exe,然后把ClassLibrary1.dll扔到该运行目录。你应该看到如下输出之后ClassLibrary1.dll会自动消失。