VS Extension - 从嵌入式代码编辑器中禁用错误

时间:2014-07-31 08:13:56

标签: c# vs-extensibility

我想在wpf控件中显示带有语法高亮和主题着色的c#源代码。这仅供预览,我不需要任何编辑功能。

我找到了一些关于如何嵌入代码编辑器的代码示例,该代码编辑器接收要加载的文件路径。

我用我创建的临时文件加载它 - 它的工作原理,差不多......

问题是加载的代码有解析错误,显示在错误列表中。

有没有办法将这些错误设置为不出现在错误列表中?

以下是代码:

IVsInvisibleEditorManager invisibleEditorManager = (IVsInvisibleEditorManager)ServiceProvider.GlobalProvider.GetService(typeof(SVsInvisibleEditorManager));

ErrorHandler.ThrowOnFailure(invisibleEditorManager.RegisterInvisibleEditor(csTempFilePath, pProject: null,dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING,
                                                                           pFactory: null, ppEditor: out this.invisibleEditor));

//The doc data is the IVsTextLines that represents the in-memory version of the file we opened in our invisibe editor, we need
//to extract that so that we can create our real (visible) editor.
IntPtr docDataPointer = IntPtr.Zero;
Guid guidIVSTextLines = typeof(IVsTextLines).GUID;
ErrorHandler.ThrowOnFailure(this.invisibleEditor.GetDocData(fEnsureWritable: 1, riid: ref guidIVSTextLines, ppDocData: out docDataPointer));

try
{
    IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer);

    //Get the component model so we can request the editor adapter factory which we can use to spin up an editor instance.
    IComponentModel componentModel = (IComponentModel)ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel));
    IVsEditorAdaptersFactoryService editorAdapterFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();

    //Create a code window adapter.
    this.codeWindow = editorAdapterFactoryService.CreateVsCodeWindowAdapter(OleServiceProvider);

    IVsCodeWindowEx codeWindowEx = (IVsCodeWindowEx)this.codeWindow;
    INITVIEW[] initView = new INITVIEW[1];
    codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER,
                             VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter,
                             szNameAuxUserContext: "",
                             szValueAuxUserContext: "",
                             InitViewFlags: 0,
                             pInitView: initView);

    ErrorHandler.ThrowOnFailure(this.codeWindow.SetBuffer((IVsTextLines)docData));

    //Get our text view for our editor which we will use to get the WPF control that hosts said editor.
    ErrorHandler.ThrowOnFailure(this.codeWindow.GetPrimaryView(out this.textView));

    //Get our WPF host from our text view (from our code window).
    IWpfTextViewHost textViewHost = editorAdapterFactoryService.GetWpfTextViewHost(this.textView);

    textViewHost.TextView.Options.SetOptionValue(DefaultTextViewHostOptions.ChangeTrackingId, false);
    textViewHost.TextView.Options.SetOptionValue(DefaultTextViewOptions.ViewProhibitUserInputId, true);

    var dte = ContainerFactory.GetContainer().Resolve<DTE2>();
    var projectItem = dte.Solution.FindProjectItem(csTempFilePath);
    projectItem.Properties.Item("BuildAction").Value = prjBuildAction.prjBuildActionNone;

    return textViewHost.HostControl;
}
finally
{
    if (docDataPointer != IntPtr.Zero)
    {
        //Release the doc data from the invisible editor since it gave us a ref-counted copy.
        Marshal.Release(docDataPointer);
    }
}

我尝试手动删除错误列表中的错误。但它不起作用 - 我认为这是因为我只能删除我之前添加的错误。这是我尝试用来删除错误的代码:

public void RemoveTempFileErrors()
{
    var provider = new ErrorListProvider(ServiceProvider.GlobalProvider)
        {
            ProviderName = "MyProvider",
            ProviderGuid = new Guid("41C0915D-A0F4-42B2-985F-D1CC5F65BFFC") // my provider guid
        };

    var vsTaskList1 = (IVsTaskList) Package.GetGlobalService(typeof (IVsTaskList));
    uint providerCookie;
    vsTaskList1.RegisterTaskProvider(provider, out providerCookie);

    vsTaskList1.RefreshTasks(providerCookie);

    var vsTaskList2 = (IVsTaskList2)Package.GetGlobalService(typeof(IVsTaskList));

    provider.SuspendRefresh();
    IVsEnumTaskItems enumerator;
    vsTaskList1.EnumTaskItems(out enumerator);
    IVsTaskItem[] arr = new IVsTaskItem[1];
    while (enumerator.Next(1, arr, null) == 0)
    {
        string doc;
        arr[0].Document(out doc);
        if (doc == csTempFilePath)
        {
            vsTaskList2.RemoveTasks(providerCookie, 1, arr);
        }            
    }

    provider.ResumeRefresh();
    provider.Refresh();
    vsTaskList1.UnregisterTaskProvider(providerCookie);
}

1 个答案:

答案 0 :(得分:0)

我部分解决了 -

解析错误是由于代码是没有类的方法引起的。所以我将方法包装在一个类中,并使用一个elision缓冲区来显示没有包装类的方法

elision缓冲区代码如下:

var subsetSnapshot = new SnapshotSpan(textSnapshot.Lines.First().EndIncludingLineBreak, textSnapshot.Lines.Last().Start);

var projectionBufferFactory = componentModel.GetService<IProjectionBufferFactoryService>();

var projBuffer = projectionBufferFactory.CreateElisionBuffer(null, 
new NormalizedSnapshotSpanCollection(subsetSnapshot), ElisionBufferOptions.None);

IVsTextBuffer bufferAdapter = editorAdapterFactoryService.CreateVsTextBufferAdapterForSecondaryBuffer(OleServiceProvider, projBuffer);

projTextView = editorAdapterFactoryService.CreateVsTextViewAdapter(OleServiceProvider);

projTextView.Initialize((IVsTextLines)bufferAdapter, IntPtr.Zero, 
    (uint)TextViewInitFlags.VIF_HSCROLL | (uint)TextViewInitFlags.VIF_VSCROLL | (uint)TextViewInitFlags3.VIF_NO_HWND_SUPPORT,
    new[] { new INITVIEW { fSelectionMargin = 0, fWidgetMargin = 0, fVirtualSpace = 0, fDragDropMove = 0 } };

IWpfTextViewHost projTextViewHost = editorAdapterFactoryService.GetWpfTextViewHost(projTextView);