c# - 罗斯林 : Get Current Project/Get Current Doc that is selected

标签 c# roslyn

我正在为我的团队开发一个代码生成器 (VSIX),在我与 VSIX 可扩展性框架作斗争之后,我打算使用 Roslyn 作为基础引擎。

我的代码生成器目前能够为解决方案生成一个新的 csproj,并且能够基于 VSIX 可扩展性的模板项目生成样板代码库。尽管我雄心勃勃,但我尽量不依赖静态模板项目,而是使用 Roslyn 来制作代码。

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

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

我曾尝试使用 AdhocWorkspace,但由于我无法获得任何东西,所以到目前为止都失败了。

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

谢谢。

最佳答案

对于 #1 的一些代码,我必须做同样的事情。我正在用光标做一些事情,所以我要通过 caretPosition(光标)。还有其他方法,但要点是相同的,获取当前的 TextView ,然后从那里转到 Roslyn。

您将需要安装 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
}

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

这真的很难看,但我从另一个 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"))

关于c# - 罗斯林 : Get Current Project/Get Current Doc that is selected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36218148/

相关文章:

c# - 在按钮/链接点击上调用 javascript 和 C#

C# ToString继承

c# - 如何在 Roslyn 中禁用不必要的 using 指令检查?

c# - 如何在 Entity Framework 数据上下文中的属性名称中使用 sql 保留关键字?

c# - 如何在 C# 中为我的猜谜游戏编写 if 语句

c# - 许多 VBCSCompiler.exe 实例

c# - 使用 Roslyn 进行面向方面的编程

c# - 如何确定哪个 SemanticModel 实例解析 ExpressionSyntax

c# - 需要 CRC 编程帮助,从 .NET 类到 C 的 CRC32 转换

c# - ObjectCreationExpressionSyntax.Type 的 SemanticModel.GetTypeInfo() 返回 null