标签:
结构图
生成目录和新的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,基本思想就是这样子了。
利用Appdomain动态加载程序集,实现更灵活的vs2012外接程序开发
标签:
原文地址:http://my.oschina.net/hunjixin/blog/508274