利用Appdomain动态加载程序集,实现更灵活的vs2012外接程序开发

结构图

生成目录和新的appdomain基目录相同,随时生成,随时加载。

接口代码

    public interface FuncProcessings 
    { 
        void GetFunctionMessage(FuncMessage funcMessage);
        string ReturnResult();
    }
    [Serializable]
   public struct FuncMessage
    {
        private string projectMessage;
        private string _head;
        private string _body;
        private string _foot;

        public string Head { get { return _head; } set { _head = value; } }
        public string Body { get { return _body; } set { _body = value; } }
        public string Foot { get { return _foot; } set { _foot = value; } }
        public string ProjectMessage { get { return projectMessage; } set { projectMessage = value;     }

这里构造的类和结构体需要加上serializable序列化特性,用于数据传输

处理逻辑

public class Processing : MarshalByRefObject, ProcessingInterface.FuncProcessings
    {
        public Processing()
        { }
        public void GetFunctionMessage(FuncMessage funcMessage)
        {
            string basePath = string.Empty;
            string activingFile = string.Empty;
            string selectedTest = string.Empty;
            string[] projrctStr = funcMessage.ProjectMessage.Split(‘$‘);
            if (projrctStr.Length < 3)
            {
                basePath = projrctStr[0];
                activingFile = projrctStr[1];
            }
            if (projrctStr.Length < 4)
            {
                selectedTest = projrctStr[2];
            }
            string message = string.Format("----工程名----\r\n{0}\r\n----激活文件----\r\n{1}\r\n----已选文本----\r\n{2}\r\n----程序头部----\r\n{3}\r\n----函数----\r\n{4}\r\n----程序结尾----\r\n",
                              basePath,
                              activingFile,
                              selectedTest,
                              funcMessage.Head.Replace(" ", ""),
                              funcMessage.Body.Replace(" ", ""),
                              funcMessage.Foot.Replace(" ", ""));
            GlobalVariables.functionString = message;

        }
        public string ReturnResult()
        {
            return GlobalVariables.functionString;
        }
    }

类需要继承MarshalByRefObject用于Appdomain边界引用

外接程序

  if (_applicationObject != null)
            {
                string projectmess = _applicationObject.ActiveWindow.Project.FullName + ‘$‘                          //项目名称
                                     + _applicationObject.ActiveDocument.FullName.Trim() + "$"                        //文件
                                     + ((TextSelection)_applicationObject.ActiveDocument.Selection).Text.Trim();     //被选文本

                string appPath = @"C:\Users\Administrator\Desktop\work";
                string assemblyPath = @"D:\我的文档\Visual Studio 2012\Projects\FuncTest\FuncTest\bin\Debug\AddFunc.dll";

                FuncMessage funcMessage = new FuncMessage();
                funcMessage.ProjectMessage = projectmess;
                funcMessage.Head = this.HeaderText.Text.Trim();
                funcMessage.Body = this.BodyText.Text.Trim();
                funcMessage.Foot = this.FootText.Text.Trim();

                AppDomainSetup setup = new AppDomainSetup();
                setup.ApplicationName = "ModelLoad";
                setup.ApplicationBase = appPath;// AppDomain.CurrentDomain.BaseDirectory;
                setup.PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "private");
                setup.CachePath = setup.ApplicationBase;
                setup.ShadowCopyFiles = "true";
                setup.ShadowCopyDirectories = setup.ApplicationBase;
                appDomain = AppDomain.CreateDomain("ModelLoadDomain", null, setup);
                string name = Assembly.LoadFrom(assemblyPath).GetName().FullName;

                IFunc = (FuncProcessings)appDomain.CreateInstanceAndUnwrap(
                name,
                typeof(Processing).FullName);

                IFunc.GetFunctionMessage(funcMessage);
                ResultForm rf = new ResultForm(IFunc.ReturnResult());
                rf.ShowDialog();

外接程序和应用程序有所区别,外接程序的工作目录并非是当前的工作目录,尽管编辑器不会报错但是运行时会报错,所以引用的结构和dll需要放到安装目录下common7下的ide内,这里放置processing的基类更加合适,用于创建实例,事实上这里需要只是类型,实现是在跨边界引用的对象里。

 setup.ApplicationBase = appPath;// AppDomain.CurrentDomain.BaseDirectory;

正常的程序是使用注释后的路径即可在debug下创建新域的目录,由于外接程序的特殊性,此处获取的并非是真正需要的目录,所以我在这里指定绝对路径,然而将这个路径指定为处理程序的debug目录也当是个不错的主意。

测试结果

取消注释,生成。vs并未重启。

ok,基本思想就是这样子了。

时间: 2025-01-02 14:57:00

利用Appdomain动态加载程序集,实现更灵活的vs2012外接程序开发的相关文章

C# 动态加载程序集信息

在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载Dll需要的知识点. 涉及知识点: AssemblyName类,完整描述程序集的唯一标识, 用来表述一个程序集. Assembly类,在System.Reflection命名空间下,表示一个程序集,它是一个可重用.无版本冲突并且可自我描述的公共语言运行时应用程序构建基块. Module类 表述在模块上执行反射,表述一个程序集的模块信息. Type类,在System命名空间下,表示类型声明:类类型.接口类型.数组

C# 动态加载程序集dll (实现接口)

一.程序集(接口程序集):LyhInterface.Dll namespace LyhInterface{    public interface ILyhInterface    {        void Run();    }} 二.程序集(实现接口的程序集):LyhClassLibrary1.dll, LyhClassLibrary2.dll,LyhClassLibrary3.dll,所有程序集引用:LyhInterface.dll namespace LyhClassLibrary1{

利用反射动态加载程序集中所有的继承于Form的子类

利用C# 的反射,能够轻松快捷的创建指定类型的未知对象,比如继承某个接口的类,继承于某个基类的子类. 问题场景: 我自己创建一个解决方案,这个方案里面放了很多的小工具,每一个工具都是一个小窗体,于是,我就用一个MID窗体来包含这些窗体. 这样问题就来了,每一次我添加一个小工具,我就必须在MID窗体里面添加一个按钮,或者是一个菜单.在事件写上,让某个窗体显示出来.这类无聊的语句. 那么能不能让程序自动查找程序集中的窗体,自动创建按钮,或者菜单. 这样就可以达到动态创建的目的了 解决方案: 假设我们

java反射并不是什么高深技术,面向对象语言都有这个功能,而且功能也很简单,就是利用jvm动态加载时生成的class对象

java反射并不是什么高深技术,面向对象语言都有这个功能. 面向对象语言都有这个功能,而且功能也很简单,就是利用jvm动态加载时生成的class对象,去获取类相关的信息 2.利用java反射可以调用类的私有方法么?private()方法 答:可以,class取出method,method继承executable类,executable类继承AccessibleObject类,AccessibleObject有个setAccessiable()设置这个方法是否可访问. 则设置成true,就可将pr

利用DexClassLoader动态加载dex文件

Java中也有类加载器ClassLoader,其作用是动态装载Class文件,当我们从网络下载Class文件,或者在编译时不参与而在运行时动态调用时就需要用类加载器.由于Android对class文件进行了重新打包和优化,最终APK文件中包含的是dex文件,加载这种文件就需要用到DexClassLoader. DexClassLoader(dexPath, optimizedDirectory, libraryPath, parent) dexPath:目标类所在的APK或者jar包,/.../

asp.net动态加载程序集创建指定类的实例及调用指定方法

以下类中有三个方法: LoadAssembly:加载指定路径的程序集 GetInstance:根据Type动态获取实例,用泛型接到返回的类型 ExecuteMothod:执行实例中的指定方法 /// <summary> /// 继承自MarshalByRefObject表示允许跨域通信 /// </summary> public class RemoteLoader : MarshalByRefObject { private Assembly _assembly; public

Java抓取利用JS动态加载的网页

最近实验室项目涉及到很多爬虫相关的东西,在此做个整理,爬虫最难的问题应该是javascript和ajax的处理.现在很多网站使用大量ajax,普通爬虫无法获取js生成的内容. 对于普通的静态网页,HttpClient是Java中抓取网页的利器,然而针对像京东商品页面这样的页面却无能为力,例如:http://item.jd.com/10875285.html 主要原因是页面中的一部分信息比如商品评论是通过JavaScript异步加载的,如果直接通过HttpClient直接抓取只会得到其中的js代码

WPF 利用BackgroundWorker 动态加载UI

BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += (ee, se) => { //TODO 需要异步请求的操作 }; bw.RunWorkerCompleted += (ew, sw) => { Dispatcher.Invoke(new Action(() => { <span style="white-space:pre"> </span>//TODO 动态生成UI }))

.Net之动态加载程序集

//路径规则所在的dll System.Reflection.Assembly ass=System.Relection.Assembly.Load("PathCheck"); //创建该实例           注意:必须使用名称空间+类名称 Object obj=ass.CreateInstance("PathCheck.SualApplyLowDistrictPrincipalCommit"); 实例: 为了以后的扩展和维护,一般情况下,需要创建一个父类,暂且