结构图
生成目录和新的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,基本思想就是这样子了。