和我一起学VSTA(Visual Studio Tools for Applications )(四)

前三篇简单介绍了VSTA的用途以及开发前期准备,这一篇将介绍具体的开发。

我们先实现一个最简单的功能,打开VSTA IDE编程环境。

首先在VSTASAMPLE项目中,添加如下引用:

 

 

以及:

Microsoft Development Enviroment 8.0.

DTEProvider 1.0 Type Library

 

添加HostItemProvider.cs,代码如下:

 

 1 using  System;
 2 using  System.Collections.Generic;
 3 using  System.Text;
 4 using  System.AddIn.Contract;
 5 using  System.AddIn.Contract.Automation;
 6 using  System.Runtime.Remoting;
 7 using  Microsoft.VisualStudio.Tools.Applications.Contract;
 8 using  Microsoft.VisualStudio.Tools.Applications;
 9
10 namespace  VSTASample
11 ExpandedBlockStart.gifContractedBlock.gif {
12    internal class HostItemProvider : ContractAdapterBase,
13    IHostItemProviderContract
14ExpandedSubBlockStart.gifContractedSubBlock.gif    {
15        private VSTAApplication application;
16
17        public HostItemProvider( VSTAApplication application,
18            TypeInfrastructureManager typeInfrastructureManager )
19            : base(typeInfrastructureManager)
20ExpandedSubBlockStart.gifContractedSubBlock.gif        {
21            this.application = application;
22        }

23
24        protected override IContract QueryContract( string contractId )
25ExpandedSubBlockStart.gifContractedSubBlock.gif        {
26            if(String.Compare(contractId,
27                typeof(IHostItemProviderContract).AssemblyQualifiedName,
28                StringComparison.Ordinal) == 0)
29ExpandedSubBlockStart.gifContractedSubBlock.gif            {
30                return (IContract)this;
31            }

32
33            return base.QueryContract(contractId);
34        }

35
36        public IRemoteObjectContract GetHostObject( string objectType, string cookie )
37ExpandedSubBlockStart.gifContractedSubBlock.gif        {
38            if(String.Compare(objectType,
39                typeof(RCS.Common.VSTA.VSTAApplication).FullName,
40                StringComparison.Ordinal) == 0)
41ExpandedSubBlockStart.gifContractedSubBlock.gif            {
42                RemoteObjectAdapter adapter = new RemoteObjectAdapter(
43                    typeof(RCS.Common.VSTA.VSTAApplication),
44                    application, TypeInfrastructureManager);
45                return adapter;
46            }

47
48            throw new ArgumentOutOfRangeException();
49        }

50
51        protected override string RemoteToString()
52ExpandedSubBlockStart.gifContractedSubBlock.gif        {
53            return this.ToString();
54        }

55
56        protected override int GetRemoteHashCode()
57ExpandedSubBlockStart.gifContractedSubBlock.gif        {
58            return this.GetHashCode();
59        }

60
61        protected override bool RemoteEquals( IContract contract )
62ExpandedSubBlockStart.gifContractedSubBlock.gif        {
63            if(contract == null)
64                return false;
65
66            if(!System.Runtime.Remoting.RemotingServices.
67                IsObjectOutOfAppDomain(contract))
68ExpandedSubBlockStart.gifContractedSubBlock.gif            {
69                HostItemProvider contractAdapter =
70                    contract as HostItemProvider;
71                return this.Equals(contractAdapter);
72            }

73
74            return false;
75        }

76    }

77}

78

 添加一个IDEManagement.cs,代码如下:

 

  1 using  System;
  2 using  System.Collections.Generic;
  3 using  System.Text;
  4 using  System.Reflection;
  5 using  System.Windows.Forms;
  6 using  Microsoft.VisualStudio.Tools.Applications;
  7 using  Microsoft.VisualStudio.Tools.Applications.Contract;
  8 using  Microsoft.VisualStudio.Tools.Applications.DesignTime.Interop;
  9 using  System.AddIn.Contract.Automation;
 10 using  EnvDTE80;
 11 using  VSTADTEProvider.Interop;
 12 using  System.IO;
 13 using  System.Collections;
 14 using  EnvDTE;
 15
 16 namespace  VSTASample
 17 ExpandedBlockStart.gifContractedBlock.gif {
 18ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 19    /// VSTA操作方法类
 20    /// </summary>

 21    internal partial class IDEManagement
 22ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 23        private VSTAApplication application;
 24        //private Context macroContext;
 25        //private AddInCollection addInCollection;
 26        private IHostItemProviderContract itemProvider;
 27        private TypeInfrastructureManager typeInfrastructureManager;
 28        private EnvDTE.DTE vstaDTE;
 29        private EnvDTE.Project macroProject; 
 30        //private IEntryPointContract[] hostItems;
 31        private string hostID;
 32        private string templateName;
 33
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 35        /// 初始化Extension类的新实例。
 36        /// </summary>

 37        internal IDEManagement()
 38ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 39            InitializeTypeInfrastructureManager();
 40        }

 41
 42        
 43        internal void Connect(VSTAApplication application, string hostID,string templateName)
 44ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 45            this.application = application;
 46            this.application.IDEManagement = this;
 47            this.hostID = hostID;
 48            this.templateName = templateName;
 49
 50            this.itemProvider = new HostItemProvider(application,TypeInfrastructureManager);
 51            //this.macroPath = @"C:\ShapeAppSamples\MyVSTADLLTest\Macros\bin";
 52            //LoadAddIns();
 53            //InitializeMenus();
 54
 55        }
  
 56        
 57ContractedSubBlock.gifExpandedSubBlockStart.gif       Internal Properties#region Internal Properties
 58
 59        internal TypeInfrastructureManager TypeInfrastructureManager
 60ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 61            get
 62ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 63                return typeInfrastructureManager;
 64            }

 65        }

 66        #endregion

 67
 68ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 69        /// 打开脚本编程环境
 70        /// </summary>
 71        /// <param name="projectDirectory">脚本程序所在目录</param>
 72        /// <param name="projectFilename">脚本程序工程文件名称(*.vbproj)</param>
 73        /// <returns></returns>

 74        public bool StartIDE(string projectDirectory, string projectFilename)
 75ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 76            EnsureIDE(hostID);
 77            if (vstaDTE.MainWindow.Visible)
 78ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 79                //vstaDTE.MainWindow.Activate();
 80                vstaDTE.MainWindow.SetFocus();
 81                return true;
 82            }

 83            else
 84ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 85                vstaDTE.MainWindow.Visible = true;
 86                vstaDTE.MainWindow.WindowState = EnvDTE.vsWindowState.vsWindowStateMaximize;
 87                string projectFilePath = System.IO.Path.Combine(projectDirectory, projectFilename);
 88                if (System.IO.File.Exists(projectFilePath))
 89ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 90                    OpenMacroProject(projectFilePath);
 91                }

 92                else
 93ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 94                    try
 95ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
 96                        CreateNewMacroProject(projectDirectory, projectFilename);
 97                    }

 98                    catch(Exception e)
 99ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
100                        MessageBox.Show(
101                            e.Message,
102                            hostID, MessageBoxButtons.OK, MessageBoxIcon.Error);
103                        this.vstaDTE.Quit();
104                        vstaDTE = null;
105                        return false;
106                    }

107                }

108                return true;
109            }

110        }

111
112        private void EnsureIDE(string hostID)
113ExpandedSubBlockStart.gifContractedSubBlock.gif        {
114            if (this.vstaDTE == null)
115ExpandedSubBlockStart.gifContractedSubBlock.gif            {
116                try
117ExpandedSubBlockStart.gifContractedSubBlock.gif                {
118                    IDTEProvider dteProvider = new VSTADTEProviderClass();
119                    //string HostID = "MyVSTADLLTest";
120                    UInt32 TimeOut = 10000;
121                    vstaDTE = dteProvider.GetDTE(hostID, TimeOut);
122                    System.Diagnostics.Debug.Assert(this.vstaDTE != null);
123                }

124                catch
125ExpandedSubBlockStart.gifContractedSubBlock.gif                {
126                    // If DTEProvider does not work, try co-creating DTE instead.
127                    object objDTE = new EnvDTE.DTE();
128                    this.vstaDTE = (EnvDTE.DTE)objDTE;
129                }

130
131                //vstaDTE.MainWindow.Visible = true;
132                //增加关闭IDE窗口时关闭vsta.exe进程以及编译
133                EnvDTE.CommandEvents commandEvents = vstaDTE.Events.get_CommandEvents("{00000000-0000-0000-0000-000000000000}"0);
134
135                commandEvents.BeforeExecute += new EnvDTE._dispCommandEvents_BeforeExecuteEventHandler(commandEvents_BeforeExecute);
136
137                //get and subscribe to the File.Exit event prior to execution
138                EnvDTE.CommandEvents exitCommand = vstaDTE.Events.get_CommandEvents("{5EFC7975-14BC-11CF-9B2B-00AA00573819}"229);
139
140                exitCommand.BeforeExecute += new EnvDTE._dispCommandEvents_BeforeExecuteEventHandler(exitCommand_BeforeExecute);
141            }

142        }

143
144ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
145        /// 关闭IDE
146        /// </summary>

147        public void ExitIDE()
148ExpandedSubBlockStart.gifContractedSubBlock.gif        {
149            if(this.vstaDTE != null)
150ExpandedSubBlockStart.gifContractedSubBlock.gif            {
151                if(this.vstaDTE.Mode == EnvDTE.vsIDEMode.vsIDEModeDebug)
152ExpandedSubBlockStart.gifContractedSubBlock.gif                {
153                    this.vstaDTE.Debugger.Stop(true);
154                }

155                this.macroProject.Save(null);
156                this.vstaDTE.Quit();
157            }

158         private void CreateNewMacroProject(string projectDirectory, string projectFileName)
159ExpandedSubBlockStart.gifContractedSubBlock.gif        {
160            Solution2 sol = (Solution2)vstaDTE.Solution;
161            //string projectTemplatePath = @"C:\ShapeAppSamples\VSTATest\templates\VisualBasic\1033\";
162            string projectTemplatePath = sol.GetProjectTemplate(templateName, "VisualBasic");
163            //string targetProjectDirectory = @"C:\ShapeAppSamples\MyVSTADLLTest\Macros";
164            //string targetProjectFilename = "MyEventSampleMacro.vbproj";
165
166            this.vstaDTE.Solution.AddFromTemplate(projectTemplatePath,projectDirectory, projectFileName, true);
167            this.vstaDTE.Solution.SolutionBuild.Build(true);
168        }

169        
170        private void OpenMacroProject(string projectFilePath)
171ExpandedSubBlockStart.gifContractedSubBlock.gif        {
172            //string projectFilePath = @"C:\ShapeAppSamples\MyVSTADLLTest\Macros\MyEventSampleMacro.vbproj";
173            this.macroProject = this.vstaDTE.Solution.AddFromFile(projectFilePath, true);
174            //vstaDTE.MainWindow.Visible = true;
175        }

176
177        EnvDTE.CodeElement FindCodeElementInCodeElements(EnvDTE.CodeElements codeElems, EnvDTE.vsCMElement kind, string fullName)
178ExpandedSubBlockStart.gifContractedSubBlock.gif        {
179            foreach (EnvDTE.CodeElement codeElem in codeElems)
180ExpandedSubBlockStart.gifContractedSubBlock.gif            {
181                if (codeElem.Kind == kind)
182ExpandedSubBlockStart.gifContractedSubBlock.gif                {
183                    if (codeElem.FullName == fullName)
184ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
185                        if (codeElem.Kind == EnvDTE.vsCMElement.vsCMElementFunction)
186ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
187                            EnvDTE.CodeFunction codeFunc = (EnvDTE.CodeFunction)codeElem;
188                            if (codeFunc.IsOverloaded)
189ExpandedSubBlockStart.gifContractedSubBlock.gif                            {
190                                if (codeFunc.Parameters.Count != 0)
191ExpandedSubBlockStart.gifContractedSubBlock.gif                                {
192                                    continue;
193                                }

194                            }

195                        }

196
197                        return codeElem;
198                    }

199                }

200            }

201
202            return null;
203        }

204        private void exitCommand_BeforeExecute( string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault )
205ExpandedSubBlockStart.gifContractedSubBlock.gif        {
206            //Project.IsDirty is always false, so use .Saved which starts true
207            if(this.macroProject.Saved == true)
208ExpandedSubBlockStart.gifContractedSubBlock.gif            {
209                //prompt the user to save the project
210                this.macroProject.Save(null);
211                //change the saved state
212                this.macroProject.Saved = false;
213
214                this.vstaDTE.Solution.SolutionBuild.Build(true);
215            }

216
217            //quit the IDE
218            this.vstaDTE.Quit();
219
220            this.vstaDTE = null;
221        }

222
223        private void commandEvents_BeforeExecute( string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault )
224ExpandedSubBlockStart.gifContractedSubBlock.gif        {
225            EnvDTE.Command objCommand = default(EnvDTE.Command);
226            //string sCommandName = null;
227
228            //break here to check out any commands you are interested in
229            objCommand = vstaDTE.Commands.Item(Guid, ID);
230
231            //if((objCommand != null))
232            //{
233            //    sCommandName = objCommand.Name;
234
235            //    if(sCommandName.Equals("Something.WorthWatching"))
236            //    {
237            //        //do something
238            //    }
239            //}
240
241        }

242        private void InitializeTypeInfrastructureManager()
243ExpandedSubBlockStart.gifContractedSubBlock.gif        {
244            if (typeInfrastructureManager == null)
245ExpandedSubBlockStart.gifContractedSubBlock.gif            {
246                typeInfrastructureManager = new TypeInfrastructureManager();
247
248                // This was auto-generated from ProxyGen with the /h:hostmapfile commandline argument.
249
250                global::System.Type hostType;
251                global::System.Type proxyType;
252
253
254                                hostType = typeof(global::VSTASample.VSTAApplication);
255                proxyType = typeof(NonProxiableType<global::VSTASample.VSTAApplication>);
256                typeInfrastructureManager.CanonicalNameToTypeMap.Add("VSTASample, VSTASample.VSTAApplication", proxyType);
257                typeInfrastructureManager.TypeToCanonicalNameMap.Add(hostType, "VSTASample, VSTASample.VSTAApplication");
258            }

259       }

260  }

261}

这里,我们为了方便不同的项目调用,用一个操作类来发布,添加一个VSTAHelper.cs,代码如下:

 

  1 using  System;
  2 using  System.Collections.Generic;
  3 using  System.Text;
  4 using  System.Reflection;
  5 using  EnvDTE;
  6 using  System.Collections;
  7
  8 namespace  VSTASample
  9 ExpandedBlockStart.gifContractedBlock.gif {
 10ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 11    /// VSTA操作类
 12    /// </summary>

 13    public class VSTAHelper
 14ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 15        private static VSTAHelper instance;
 16
 17ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 18        /// VSTAHelper类单一实例
 19        /// </summary>

 20        public static VSTAHelper Instance
 21ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 22            get
 23ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 24                if(VSTAHelper.instance == null)
 25ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 26                    VSTAHelper.instance = new VSTAHelper();
 27                }

 28
 29                return VSTAHelper.instance;
 30            }

 31        }

 32
 33        private VSTAApplication app;
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 35        /// 初始化类的实例。
 36        /// </summary>

 37        private VSTAHelper()
 38ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 39ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 40                app = new VSTAApplication();
 41            }

 42        }

 43
 44ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 45        /// 打开脚本编程环境
 46        /// </summary>
 47        /// <returns></returns>
 48        /// <param name="projectDirectory">脚本程序所在目录(如:C:\ShapeAppSamples\MyVSTADLLTest\Macros)</param>
 49        /// <param name="projectFilename">脚本程序工程文件名称(*.vbproj)</param>
 50        /// <example><code>
 51        /// private VSTAHelper vstaHelper = new VSTAHelper();
 52        /// vstaHelper.StartIDE(@"..\Solutions\自动计量\script\Demo","Demo.vbproj");
 53        /// </code></example>

 54        public void StartIDE( string projectDirectory, string projectFilename )
 55ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 56            //using(MessageFilter messageFilter = new MessageFilter())
 57ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 58                app.IDEManagement.StartIDE(projectDirectory, projectFilename);
 59            }

 60        }

 61
 62ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 63        /// 关闭IDE
 64        /// </summary>
 65        /// <example><code>
 66        /// private VSTAHelper vstaHelper = new VSTAHelper();
 67        /// vstaHelper.ExitIDE();
 68        /// </code></example>

 69        public void ExitIDE()
 70ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 71            app.IDEManagement.ExitIDE();
 72        }

 73
 74    }

 75    internal partial class VSTAApplication
 76ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 77        private IDEManagement ideManagement;
 78ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 79        /// 操作方法类
 80        /// </summary>

 81        public IDEManagement IDEManagement
 82ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 83            get
 84ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 85                if(this.ideManagement == null)
 86ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 87                    ideManagement = new IDEManagement();
 88                    ideManagement.Connect(this"VSTAHelper""dlladdin.zip");
 89                }

 90                return ideManagement;
 91            }

 92            set
 93ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 94                ideManagement = value;
 95            }

 96        }

 97
 98    }

 99}

100

编译生成。

下面就是新建个winform项目,使用操作类即可。

VSTASample.VSTAHelper.Instance.StartIDE(projectPath,projectFileName);

转载于:https://www.cnblogs.com/solsolsol/archive/2009/06/22/1508405.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值