前面四章是介绍,我们已经可以成功的通过一个winform程序打开一个VSTA的IDE编程窗口进行二次开发,但是对于我们使用来说是远远不够的,对于二次开发来说,最重要的一点是从主程序调用二次开发时编写的方法。
这一篇,我就简单介绍下如何调用VSTAIDE中编写的方法。
这里调用方法,第一步就是加载VSTA IDE中编写的代码编译而成的程序集(dll文件)到Microsoft.VisualStudio.Tools.Applications.AddIn和Contex中,第二步将准备调用的方法名称传给MethodInfo,通过反射调用实际方法,第三步不再需要使用的时候卸载程序集。
下面用代码进行讲解。
首先在VSTASAMPLE工程里添加一个RunManagement.cs,代码如下:
在VSTAHelper.cs的VSTAHelper类中,添加如下代码:
这一篇,我就简单介绍下如何调用VSTAIDE中编写的方法。
这里调用方法,第一步就是加载VSTA IDE中编写的代码编译而成的程序集(dll文件)到Microsoft.VisualStudio.Tools.Applications.AddIn和Contex中,第二步将准备调用的方法名称传给MethodInfo,通过反射调用实际方法,第三步不再需要使用的时候卸载程序集。
下面用代码进行讲解。
首先在VSTASAMPLE工程里添加一个RunManagement.cs,代码如下:
1
using
System;
2 using System.Collections.Generic;
3 using System.Text;
4 using Microsoft.VisualStudio.Tools.Applications;
5 using Microsoft.VisualStudio.Tools.Applications.Contract;
6 using System.AddIn.Contract.Automation;
7 using System.Reflection;
8
9 namespace VSTASample
10 {
11 /**//// <summary>
12 /// 运行态操作类
13 /// </summary>
14 internal class RunManagement
15 {
16 private VSTAApplication application;
17 private Context macroContext;
18 private AddInCollection addInCollection;
19 private IHostItemProviderContract itemProvider;
20 private TypeInfrastructureManager typeInfrastructureManager;
21 private IEntryPointContract[] hostItems;
22 private string hostID;
23 private string templateName;
24
25 private IRemoteObjectContract remoteObjectContract;
26 private RemoteObject remoteObject;
27
28
29 /**//// <summary>
30 /// 初始化RunManagement类的新实例。
31 /// </summary>
32 internal RunManagement()
33 {
34 InitializeTypeInfrastructureManager();
35 }
36
37 internal void Connect( VSTAApplication application, string hostID, string templateName )
38 {
39 this.application = application;
40 this.application.RunManagement = this;
41 this.hostID = hostID;
42 this.templateName = templateName;
43
44 this.itemProvider = new HostItemProvider(application, TypeInfrastructureManager);
45 }
46
47 运行态 Managerment#region 运行态 Managerment
48 /**//// <summary>
49 /// 执行VSTA IDE中的方法
50 /// </summary>
51 /// <param name="macroName">需执行的方法名</param>
52 /// <returns>存在方法返回true,否则返回false</returns>
53 public void ExecuteMacro( string macroName )
54 {
55 if(macroContext == null || macroContext.Count == 0 || macroContext[0].Count == 0)
56 {
57 return;
58 }
59
60 //this.hostItems = macroContext[0][0].GetEntryPoints();
61 if(this.hostItems != null)
62 {
63 MethodInfo methodInfo = remoteObject.GetType().GetMethod(macroName, new Type[0]);
64
65 if(methodInfo == null)
66 {
67 return;
68 }
69
70 try
71 {
72 methodInfo.Invoke(remoteObject, null);
73 }
74 catch(Exception ex)
75 {
76 System.Windows.Forms.MessageBox.Show(ex.Message);
77 }
78 finally
79 {
80 methodInfo = null;
81 }
82 }
83
84 }
85
86 /**//// <summary>
87 /// 加载脚本
88 /// </summary>
89 /// <param name="macroFilePath">脚本dll所在目录</param>
90 /// <param name="macroFileName">脚本dll名称(*.dll)</param>
91 public void LoadAddIns( string macroFilePath, string macroFileName )
92 {
93 if(!System.IO.File.Exists(macroFilePath + @"\" + macroFileName))
94 {
95 return;
96 //throw new Exception("没有可加载的dll");
97 }
98
99 if(macroContext == null)
100 {
101 macroContext = new Context("Application", itemProvider);
102 addInCollection = new AddInCollection();
103 macroContext.Add(addInCollection);
104 }
105 else
106 {
107 macroContext.Clear();
108 macroContext.Add(new AddInCollection());
109 //UnloadAddIns();
110 }
111
112 //AddIn addIn = new Microsoft.VisualStudio.Tools.Applications.AddIn(@"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin", @"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin\MyEventSampleMacro.dll");
113 AddIn addIn = new Microsoft.VisualStudio.Tools.Applications.AddIn(macroFilePath, System.IO.Path.Combine(macroFilePath, macroFileName));
114 addInCollection.Add(addIn);
115 //addIn.Load(@"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin");
116 addIn.Load(macroFilePath);
117
118 this.hostItems = macroContext[0][0].GetEntryPoints();
119 if(this.hostItems != null)
120 {
121 remoteObjectContract = (IRemoteObjectContract)this.hostItems[0].GetEntryPointObject().QueryContract(typeof(IRemoteObjectContract).AssemblyQualifiedName);
122 remoteObject = new RemoteObject(remoteObjectContract, new TypeInfrastructureManager());
123 }
124
125 }
126 /**//// <summary>
127 /// 卸载脚本
128 /// </summary>
129 public void UnloadAddIns()
130 {
131 if(macroContext == null)
132 return;
133 try
134 {
135 foreach(AddInCollection coll in macroContext)
136 {
137 foreach(AddIn a in coll)
138 {
139 if(a.IsLoaded)
140 a.Unload(TimeSpan.FromSeconds(5));
141 }
142 }
143 }
144 catch
145 {
146 // Ignore the exception. Throw in the case where the hosting process is shut down.
147 }
148 finally
149 {
150 macroContext = null;
151 }
152 }
153 #endregion
154
155 Internal Properties#region Internal Properties
156
157 internal TypeInfrastructureManager TypeInfrastructureManager
158 {
159 get
160 {
161 return typeInfrastructureManager;
162 }
163 }
164 #endregion
165
166 private void InitializeTypeInfrastructureManager()
167 {
168 if(typeInfrastructureManager == null)
169 {
170 typeInfrastructureManager = new TypeInfrastructureManager();
171
172 // This was auto-generated from ProxyGen with the /h:hostmapfile commandline argument.
173
174 global::System.Type hostType;
175 global::System.Type proxyType;
176
177
178 hostType = typeof(global::VSTASample.VSTAApplication);
179 proxyType = typeof(NonProxiableType<global::VSTASample.VSTAApplication>);
180 typeInfrastructureManager.CanonicalNameToTypeMap.Add("VSTASample, VSTASample.VSTAApplication", proxyType);
181 typeInfrastructureManager.TypeToCanonicalNameMap.Add(hostType, "VSTASample, VSTASample.VSTAApplication");
182 }
183 }
184 }
185}
2 using System.Collections.Generic;
3 using System.Text;
4 using Microsoft.VisualStudio.Tools.Applications;
5 using Microsoft.VisualStudio.Tools.Applications.Contract;
6 using System.AddIn.Contract.Automation;
7 using System.Reflection;
8
9 namespace VSTASample
10 {
11 /**//// <summary>
12 /// 运行态操作类
13 /// </summary>
14 internal class RunManagement
15 {
16 private VSTAApplication application;
17 private Context macroContext;
18 private AddInCollection addInCollection;
19 private IHostItemProviderContract itemProvider;
20 private TypeInfrastructureManager typeInfrastructureManager;
21 private IEntryPointContract[] hostItems;
22 private string hostID;
23 private string templateName;
24
25 private IRemoteObjectContract remoteObjectContract;
26 private RemoteObject remoteObject;
27
28
29 /**//// <summary>
30 /// 初始化RunManagement类的新实例。
31 /// </summary>
32 internal RunManagement()
33 {
34 InitializeTypeInfrastructureManager();
35 }
36
37 internal void Connect( VSTAApplication application, string hostID, string templateName )
38 {
39 this.application = application;
40 this.application.RunManagement = this;
41 this.hostID = hostID;
42 this.templateName = templateName;
43
44 this.itemProvider = new HostItemProvider(application, TypeInfrastructureManager);
45 }
46
47 运行态 Managerment#region 运行态 Managerment
48 /**//// <summary>
49 /// 执行VSTA IDE中的方法
50 /// </summary>
51 /// <param name="macroName">需执行的方法名</param>
52 /// <returns>存在方法返回true,否则返回false</returns>
53 public void ExecuteMacro( string macroName )
54 {
55 if(macroContext == null || macroContext.Count == 0 || macroContext[0].Count == 0)
56 {
57 return;
58 }
59
60 //this.hostItems = macroContext[0][0].GetEntryPoints();
61 if(this.hostItems != null)
62 {
63 MethodInfo methodInfo = remoteObject.GetType().GetMethod(macroName, new Type[0]);
64
65 if(methodInfo == null)
66 {
67 return;
68 }
69
70 try
71 {
72 methodInfo.Invoke(remoteObject, null);
73 }
74 catch(Exception ex)
75 {
76 System.Windows.Forms.MessageBox.Show(ex.Message);
77 }
78 finally
79 {
80 methodInfo = null;
81 }
82 }
83
84 }
85
86 /**//// <summary>
87 /// 加载脚本
88 /// </summary>
89 /// <param name="macroFilePath">脚本dll所在目录</param>
90 /// <param name="macroFileName">脚本dll名称(*.dll)</param>
91 public void LoadAddIns( string macroFilePath, string macroFileName )
92 {
93 if(!System.IO.File.Exists(macroFilePath + @"\" + macroFileName))
94 {
95 return;
96 //throw new Exception("没有可加载的dll");
97 }
98
99 if(macroContext == null)
100 {
101 macroContext = new Context("Application", itemProvider);
102 addInCollection = new AddInCollection();
103 macroContext.Add(addInCollection);
104 }
105 else
106 {
107 macroContext.Clear();
108 macroContext.Add(new AddInCollection());
109 //UnloadAddIns();
110 }
111
112 //AddIn addIn = new Microsoft.VisualStudio.Tools.Applications.AddIn(@"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin", @"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin\MyEventSampleMacro.dll");
113 AddIn addIn = new Microsoft.VisualStudio.Tools.Applications.AddIn(macroFilePath, System.IO.Path.Combine(macroFilePath, macroFileName));
114 addInCollection.Add(addIn);
115 //addIn.Load(@"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin");
116 addIn.Load(macroFilePath);
117
118 this.hostItems = macroContext[0][0].GetEntryPoints();
119 if(this.hostItems != null)
120 {
121 remoteObjectContract = (IRemoteObjectContract)this.hostItems[0].GetEntryPointObject().QueryContract(typeof(IRemoteObjectContract).AssemblyQualifiedName);
122 remoteObject = new RemoteObject(remoteObjectContract, new TypeInfrastructureManager());
123 }
124
125 }
126 /**//// <summary>
127 /// 卸载脚本
128 /// </summary>
129 public void UnloadAddIns()
130 {
131 if(macroContext == null)
132 return;
133 try
134 {
135 foreach(AddInCollection coll in macroContext)
136 {
137 foreach(AddIn a in coll)
138 {
139 if(a.IsLoaded)
140 a.Unload(TimeSpan.FromSeconds(5));
141 }
142 }
143 }
144 catch
145 {
146 // Ignore the exception. Throw in the case where the hosting process is shut down.
147 }
148 finally
149 {
150 macroContext = null;
151 }
152 }
153 #endregion
154
155 Internal Properties#region Internal Properties
156
157 internal TypeInfrastructureManager TypeInfrastructureManager
158 {
159 get
160 {
161 return typeInfrastructureManager;
162 }
163 }
164 #endregion
165
166 private void InitializeTypeInfrastructureManager()
167 {
168 if(typeInfrastructureManager == null)
169 {
170 typeInfrastructureManager = new TypeInfrastructureManager();
171
172 // This was auto-generated from ProxyGen with the /h:hostmapfile commandline argument.
173
174 global::System.Type hostType;
175 global::System.Type proxyType;
176
177
178 hostType = typeof(global::VSTASample.VSTAApplication);
179 proxyType = typeof(NonProxiableType<global::VSTASample.VSTAApplication>);
180 typeInfrastructureManager.CanonicalNameToTypeMap.Add("VSTASample, VSTASample.VSTAApplication", proxyType);
181 typeInfrastructureManager.TypeToCanonicalNameMap.Add(hostType, "VSTASample, VSTASample.VSTAApplication");
182 }
183 }
184 }
185}
1
/**/
/// <summary>
2 /// 加载脚本
3 /// </summary>
4 /// <param name="macroFilePath">脚本dll所在目录(如:C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin)</param>
5 /// <param name="macroFileName">脚本dll名称(*.dll)</param>
6 /// <example><code>
7 /// private VSTAHelper vstaHelper = new VSTAHelper();
8 /// vstaHelper.LoadAddIns(@"..\bin","Demo.dll");
9 /// </code></example>
10 public void LoadAddIns( string macroFilePath, string macroFileName )
11 {
12 app.RunManagement.LoadAddIns(macroFilePath, macroFileName);
13 }
14
15 /**/ /// <summary>
16 /// 卸载脚本
17 /// </summary>
18 /// <example><code>
19 /// private VSTAHelper vstaHelper = new VSTAHelper();
20 /// vstaHelper.UnloadAddIns();
21 /// </code></example>
22 public void UnloadAddIns()
23 {
24 app.RunManagement.UnloadAddIns();
25 }
26
27 /**/ /// <summary>
28 /// 执行VSTA IDE中的方法
29 /// </summary>
30 /// <param name="macroName">需执行的方法名</param>
31 /// <example>
32 /// <code>
33 /// private VSTAHelper vstaHelper = new VSTAHelper();
34 /// vstaHelper.LoadAddIns(@"..\bin","Demo.dll");
35 /// vstaHelper.ExecuteMacro("btn1_Click")
36 /// </code>
37 /// </example>
38 public void ExecuteMacro( string macroName )
39 {
40 app.RunManagement.ExecuteMacro(macroName);
41 }
继续在VSTAApplication类中添加如下代码:
2 /// 加载脚本
3 /// </summary>
4 /// <param name="macroFilePath">脚本dll所在目录(如:C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin)</param>
5 /// <param name="macroFileName">脚本dll名称(*.dll)</param>
6 /// <example><code>
7 /// private VSTAHelper vstaHelper = new VSTAHelper();
8 /// vstaHelper.LoadAddIns(@"..\bin","Demo.dll");
9 /// </code></example>
10 public void LoadAddIns( string macroFilePath, string macroFileName )
11 {
12 app.RunManagement.LoadAddIns(macroFilePath, macroFileName);
13 }
14
15 /**/ /// <summary>
16 /// 卸载脚本
17 /// </summary>
18 /// <example><code>
19 /// private VSTAHelper vstaHelper = new VSTAHelper();
20 /// vstaHelper.UnloadAddIns();
21 /// </code></example>
22 public void UnloadAddIns()
23 {
24 app.RunManagement.UnloadAddIns();
25 }
26
27 /**/ /// <summary>
28 /// 执行VSTA IDE中的方法
29 /// </summary>
30 /// <param name="macroName">需执行的方法名</param>
31 /// <example>
32 /// <code>
33 /// private VSTAHelper vstaHelper = new VSTAHelper();
34 /// vstaHelper.LoadAddIns(@"..\bin","Demo.dll");
35 /// vstaHelper.ExecuteMacro("btn1_Click")
36 /// </code>
37 /// </example>
38 public void ExecuteMacro( string macroName )
39 {
40 app.RunManagement.ExecuteMacro(macroName);
41 }
1
private
RunManagement runManagement;
2 /**/ /// <summary>
3 /// 操作方法类
4 /// </summary>
5 public RunManagement RunManagement
6 {
7 get
8 {
9 if(this.runManagement == null)
10 {
11 runManagement = new RunManagement();
12 runManagement.Connect(this, "VSTAHelper", "dlladdin.zip");
13 }
14 return runManagement;
15 }
16 set
17 {
18 runManagement = value;
19 }
20 }
在Form1窗体中添加一个按钮,并添加click事件,代码如下:
2 /**/ /// <summary>
3 /// 操作方法类
4 /// </summary>
5 public RunManagement RunManagement
6 {
7 get
8 {
9 if(this.runManagement == null)
10 {
11 runManagement = new RunManagement();
12 runManagement.Connect(this, "VSTAHelper", "dlladdin.zip");
13 }
14 return runManagement;
15 }
16 set
17 {
18 runManagement = value;
19 }
20 }
1
VSTASample.VSTAHelper.Instance.LoadAddIns(
@"
C:\ShapeAppSamples\VSTASample\VSTASample\bin\macro\bin
"
,
"
Sample.dll
"
);
2 VSTASample.VSTAHelper.Instance.ExecuteMacro( " fun1 " );
运行程序,打开VSTA IDE,在Helper.vb中添加代码:
2 VSTASample.VSTAHelper.Instance.ExecuteMacro( " fun1 " );
1
Public
Function fun1()
Function fun1()
2 MsgBox("HelloWorld!")
3End Function
编译后,在主程序窗体中点击新增的按钮,调用VB程序,弹出对话框,内容为“HelloWorld!”
2 MsgBox("HelloWorld!")
3End Function