Roslyn:获取当前项目/获取所选的当前文档

时间:2016-03-25 10:24:56

标签: c# roslyn

我正在为我的团队开发代码生成器(VSIX),并且在我努力使用VSIX可扩展性框架之后,我打算将Roslyn用作基础引擎。

我的代码gen目前能够为解决方案生成一个新的csproj,并能够根据VSIX扩展性的Templating项目生成样板代码库。我很有野心,我试图不依赖静态模板项目,而是使用Roslyn来代替生成代码。

我的解决方案有一个文件夹列表,每个文件夹都有一个csproj列表。

我的问题1是我尝试使用Roslyn Workspace API来检测已在代码编辑器中打开的当前文档(.cs),或者我试图获取所选cs文件的当前文档ID我是对的单击解决方案资源管理器。

我曾尝试使用AdhocWorkspace,到目前为止我已经失败,因为我无法获得任何内容。

问题2:如果我使用AdhocWorkspace,我能否更改csproj属性中的默认命名空间?或者它目前不属于Roslyn Workspace API的功能部分?

感谢。

1 个答案:

答案 0 :(得分:2)

对于#1一些代码,我必须做同样的事情。我正在用光标做事,所以我要通过caretPosition(光标)。还有其他方法,但要点是相同的,让当前的文本视图从那里到罗斯林。

您需要安装Microsoft.CodeAnalysis.EditorFeatures.Text,这会引入所有代码分析包,但允许您使用GetOpenDocumentInCurrentContextWithChanges上应用的ITextSnapshot扩展程序

private IVsEditorAdaptersFactoryService GetEditorAdaptersFactoryService()
    {
        IComponentModel componentModel =(IComponentModel)GetService(typeof(SComponentModel));
        return componentModel.GetService<IVsEditorAdaptersFactoryService>();
    }   
private Microsoft.VisualStudio.Text.Editor.IWpfTextView GetTextView()
{
    IVsTextManager textManager = (IVsTextManager)GetService(typeof(SVsTextManager));
    if (textManager == null)
        return null;
    IVsTextView textView = null;
    textManager.GetActiveView(1, null, out textView);
    if (textView == null)
        return null;
    return GetEditorAdaptersFactoryService().GetWpfTextView(textView);
}

//code to get the doc
Microsoft.VisualStudio.Text.Editor.IWpfTextView textView = GetTextView();
if (textView != null)
{
    SnapshotPoint caretPosition = textView.Caret.Position.BufferPosition;
    Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
//do stuff with Roslyn Document
}

&#34;或者我正在尝试从解决方案资源管理器中右键单击所选cs文件的当前文档ID。&#34;

这真的很丑陋,但我从一个不同的SO帖子(不记得作者)中使用的确实运作良好。

private static bool IsSingleProjectItemSelection(out IVsHierarchy hierarchy, out uint itemid)
    {
        hierarchy = null;
        itemid = VSConstants.VSITEMID_NIL;
        int hr = VSConstants.S_OK;

        var monitorSelection = Package.GetGlobalService( typeof( SVsShellMonitorSelection ) ) as IVsMonitorSelection;
        var solution = Package.GetGlobalService( typeof( SVsSolution ) ) as IVsSolution;
        if (monitorSelection == null || solution == null)
            return false;

        IVsMultiItemSelect multiItemSelect = null;
        IntPtr hierarchyPtr = IntPtr.Zero;
        IntPtr selectionContainerPtr = IntPtr.Zero;

        try
        {
            hr = monitorSelection.GetCurrentSelection( out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr );
            if (ErrorHandler.Failed( hr ) || hierarchyPtr == IntPtr.Zero || itemid == VSConstants.VSITEMID_NIL)
                return false;
            // multiple items are selected
            if (multiItemSelect != null)
                return false;
            // there is a hierarchy root node selected, thus it is not a single item inside a project
            if (itemid == VSConstants.VSITEMID_ROOT)
                return false;

            hierarchy = Marshal.GetObjectForIUnknown( hierarchyPtr ) as IVsHierarchy;
            if (hierarchy == null)
                return false;

            Guid guidProjectID = Guid.Empty;

            if (ErrorHandler.Failed( solution.GetGuidOfProject( hierarchy, out guidProjectID ) ))
                return false;

            // if we got this far then there is a single project item selected
            return true;
        }
        finally
        {
            if (selectionContainerPtr != IntPtr.Zero)
                Marshal.Release( selectionContainerPtr );

            if (hierarchyPtr != IntPtr.Zero)
                Marshal.Release( hierarchyPtr );
        }
    }

IVsHierarchy hierarchy = null;
                uint itemid = VSConstants.VSITEMID_NIL;
                if (!IsSingleProjectItemSelection(out hierarchy, out itemid))
                    return;
                string itemFullPath = null;
                ((IVsProject)hierarchy).GetMkDocument(itemid, out itemFullPath);
                if (itemFullPath.EndsWith(".cs"))