如何从VSPackage获取当前解决方案目录?

30
以下是如何从插件中获取当前解决方案目录的方法:
_applicationObject = (DTE2)application;  // retrieved from OnConnection method
string solutionDir = System.IO.Path.GetDirectoryName(_applicationObject.Solution.FullName);

你如何通过VSPackage实现此功能?

我正在将Visual Studio插件迁移到VSPackage,因为我打算添加一些用户控件,这些控件需要与IDE进行更深入的集成。

我找到了一些关于插件与集成包相对优点的好参考资料,例如: http://nayyeri.net/visual-studio-addin-vs-integration-package-part-1

还有一些关于VSPackages的好教程,例如: http://msdn.microsoft.com/en-us/library/cc138589.aspx

我还没有找到一个好的参考资料(在msdn或其他地方)来说明插件中的高级接口(如DTE)如何映射到VSPackage中的低级接口。

是否有任何好的参考资料可帮助进行从插件接口到VSPackage接口的一般映射?


2+问题和答案与我的兴趣相关。 - Terrance
3个回答

31

我找到了针对特定问题的答案。可以通过GetService()方法获取VisualStudio.DTE对象,如下所示:

// Get an instance of the currently running Visual Studio IDE
DTE dte = (DTE)GetService(typeof(DTE));
string solutionDir = System.IO.Path.GetDirectoryName(dte.Solution.FullName);

2
当多个 Visual Studio 副本正在运行时,这段代码是否存在任何问题? - Maslow
我已经在标准模式和 hibernate 模式下使用了多个 VS 实例,并且没有遇到获取正确当前解决方案的任何问题。之前我尝试过的方法确实有问题,例如:DTE dte = (DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE"); string solutionDir = System.IO.Path.GetDirectoryName(dte.Solution.FullName); - Dave Clemmer

10

你可以通过以下函数之一获得一个DTE对象:

public static DTE GetCurrentDTE(IServiceProvider provider)
{
    /*ENVDTE. */DTE vs = (DTE)provider.GetService(typeof(DTE));
        if (vs == null) throw new InvalidOperationException("DTE not found.");
    return vs;
}

public static DTE GetCurrentDTE()
{
    return GetCurrentDTE(/* Microsoft.VisualStudio.Shell. */ServiceProvider.GlobalProvider);
}

接着,你可以从DTE.Solution中获取活动的Solution,并从DTE.Solution.Path属性中获取Solution路径。


1
好代码。现在我知道如何获取DTE对象了。但是当不编写Visual Studio扩展时,如何获取IServiceProvider呢? - Vaccano

3

如果使用IVsSolution接口,您可以使用GetSolutionInfo来获取解决方案的路径、解决方案文件名和解决方案用户选项(SUO)文件:

最初的回答。

this.solution.GetSolutionInfo(
    out string solutionDirectory,
    out string solutionFile,
    out string userOptsFile);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接