最近在做Visual Studio项目和项模板需要用到一些EnvDTE的技术,把相关代码拿出来和大家分享一下
首先是获取Visual Studio实例
在仅打开了一个实例的情况下,用GetActiveInstance即可,在打开了多个实例的情况下,可以用另外一个函数获得所有实例
这里有一个问题,如果打开了多个Visual Studio,如何知道当前正在操作的Visual Studio实例?
答案令人失望,没有什么好办法。 如果有人知道可以分享一下。
有一个变通的办法,通过打开的解决方案的名称来区分,即通过Solution Name来找到某一个VS的实例。当然,前提是要知道这个Solution的名字,于是又陷入了死循环。
然后就是找到一个特定的项目(需要传入项目特征字符或者完整名称)
然后把文件或者引用加到项目中
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Runtime.InteropServices;
- using System.Runtime.InteropServices.ComTypes;
- using EnvDTE;
- using EnvDTE80;
- using VSLangProj;
- namespace Template.AddNewItemWizard
- {
- class EnvDTEHelper
- {
- public static void AddFilesToProject(string projectName, List<string> files)
- {
- try
- {
- DTE dte = GetIntegrityServiceInstance();
- if (dte != null)
- {
- foreach (EnvDTE.Project item in dte.Solution.Projects)
- {
- if (item.Name.Contains(projectName))
- {
- foreach (string file in files)
- item.ProjectItems.AddFromFile(file);
- item.Save();
- }
- }
- }
- }
- finally
- {
- }
- }
- public static void AddProjectReferences(string projectName, Dictionary<string, string> references)
- {
- try
- {
- DTE dte = GetIntegrityServiceInstance();
- if (dte != null)
- {
- foreach (EnvDTE.Project item in dte.Solution.Projects)
- {
- if (item.Name.Contains(projectName))
- {
- VSProject vsProject = (VSProject)item.Object;
- foreach (KeyValuePair<string, string> reference in references)
- {
- if (vsProject.References.Find(reference.Key) == null)
- {
- vsProject.References.Add(reference.Value);
- }
- }
- item.Save();
- }
- }
- }
- }
- finally
- {
- }
- }
- private static DTE GetIntegrityServiceInstance()
- {
- List<string> projectNames = new List<string>();
- IEnumerable<DTE> dtes = GetAllInstances();
- if (dtes.Count() == 1)
- return dtes.First();
- foreach (DTE dte in GetAllInstances())
- {
- projectNames.Clear();
- foreach (Project project in dte.Solution.Projects)
- {
- projectNames.Add(project.Name);
- }
- if ((projectNames.Contains("Service")) && (projectNames.Contains("NUnit")))
- return dte;
- }
- return null;
- }
- private static DTE2 GetActiveInstance()
- {
- return (EnvDTE80.DTE2)Marshal.GetActiveObject("VisualStudio.DTE.11.0");
- }
- private static IEnumerable<DTE> GetAllInstances()
- {
- IRunningObjectTable rot;
- IEnumMoniker enumMoniker;
- int retVal = GetRunningObjectTable(0, out rot);
- if (retVal == 0)
- {
- rot.EnumRunning(out enumMoniker);
- IntPtr fetched = IntPtr.Zero;
- IMoniker[] moniker = new IMoniker[1];
- object punkObject = null;
- while (enumMoniker.Next(1, moniker, fetched) == 0)
- {
- IBindCtx bindCtx;
- CreateBindCtx(0, out bindCtx);
- string displayName;
- moniker[0].GetDisplayName(bindCtx, null, out displayName);
- // Console.WriteLine("Display Name: {0}", displayName);
- bool isVisualStudio = displayName.StartsWith("!VisualStudio");
- if (isVisualStudio)
- {
- //var dte = rot.GetObject(moniker) as DTE;
- //yield return dte;
- rot.GetObject(moniker[0], out punkObject);
- var dte = (DTE)(punkObject);
- yield return dte;
- }
- }
- }
- }
- [DllImport("ole32.dll")]
- private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);
- [DllImport("ole32.dll")]
- private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
- }
- }
原文地址: