Пример #1
0
        protected static IVsTextLines GetTextBufferForFile(string fileName, IList <IVsInvisibleEditor> openedInvisibleEditors)
        {
            // If the file is in RDT, get the text lines from RDT cookie.
            // If the file is not is RDT, it will open that file in invisible editor and
            // get text lines from the invisible editor docdata.
            IVsTextLines textBuffer = null;

            if (RdtManager.IsFileInRdt(fileName))
            {
                // File is in RDT
                textBuffer = RdtManager.Instance.GetTextLines(fileName);
            }
            else
            {
                IVsInvisibleEditor invisibleEditor = null;
                // File is not in RDT, open it in invisible editor.
                if (RdtManager.Instance.TryGetTextLinesAndInvisibleEditor(fileName, out invisibleEditor, out textBuffer))
                {
                    openedInvisibleEditors.Add(invisibleEditor);
                }
                else
                {
                    // Failed to get text lines or invisible editor.
                    textBuffer = null;
                }
            }
            return(textBuffer);
        }
Пример #2
0
        public static VsTextLinesFromFile Load(string fileName)
        {
            VsTextLinesFromFile vsTextLinesFromFile = null;
            IVsInvisibleEditor  invisibleEditor     = null;
            IVsTextLines        textBuffer          = null;

            if (RdtManager.IsFileInRdt(fileName))
            {
                // File is in RDT
                textBuffer = RdtManager.Instance.GetTextLines(fileName);
            }
            else
            {
                // File is not in RDT, open it in invisible editor.
                if (!RdtManager.Instance.TryGetTextLinesAndInvisibleEditor(fileName, out invisibleEditor, out textBuffer))
                {
                    // Failed to get text lines or invisible editor.
                    textBuffer = null;

                    if (invisibleEditor != null)
                    {
                        Marshal.ReleaseComObject(invisibleEditor);
                    }
                }
            }

            if (textBuffer != null)
            {
                vsTextLinesFromFile = new VsTextLinesFromFile();
                vsTextLinesFromFile._invisibleEditor = invisibleEditor;
                vsTextLinesFromFile._textBuffer      = textBuffer;
            }

            return(vsTextLinesFromFile);
        }
Пример #3
0
        private void Cleanup()
        {
            if (_docCookie != 0)
            {
                RunningDocumentTable.UnlockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, _docCookie);
            }

            _docCookie = 0;
            _CurrentInvisibleEditor = null;
        }
Пример #4
0
            /// <summary>
            ///     Constructor
            /// </summary>
            /// <param name="fileFullPath">Full path of the file.</param>
            /// <param name="invisibleEditor">Invisible editor for that temp file.</param>
            /// <param name="textBuffer">Text buffer for that temp file.</param>
            public PreviewTempFile(string fileFullPath, IVsInvisibleEditor invisibleEditor, IVsTextLines textBuffer)
            {
                ArgumentValidation.CheckForEmptyString(fileFullPath, "fileFullPath");
                ArgumentValidation.CheckForNullReference(invisibleEditor, "invisibleEditor");
                ArgumentValidation.CheckForNullReference(textBuffer, "textBuffer");

                _tempFileFullPath = fileFullPath;
                InvisibleEditor   = invisibleEditor;
                _textBuffer       = textBuffer;
            }
Пример #5
0
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (_invisibleEditor != null && disposing)
                {
                    Marshal.ReleaseComObject(_invisibleEditor);
                    _invisibleEditor = null;
                }

                _disposed = true;
            }
        }
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (_invisibleEditor != null && disposing)
                {
                    Marshal.ReleaseComObject(_invisibleEditor);
                    _invisibleEditor = null;
                }

                _disposed = true;
            }
        }
Пример #7
0
        /// <remarks>
        /// <para>The optional project is used to obtain an <see cref="IVsProject"/> instance. When this instance is
        /// provided, Visual Studio will use <see cref="IVsProject.IsDocumentInProject"/> to attempt to locate the
        /// specified file within a project. If no project is specified, Visual Studio falls back to using
        /// <see cref="IVsUIShellOpenDocument4.IsDocumentInAProject2"/>, which performs a much slower query of all
        /// projects in the solution.</para>
        /// </remarks>
        public InvisibleEditor(IServiceProvider serviceProvider, string filePath, IVsHierarchy hierarchyOpt, bool needsSave, bool needsUndoDisabled)
            : base(serviceProvider.GetMefService <IThreadingContext>(), assertIsForeground: true)
        {
            _serviceProvider = serviceProvider;
            _filePath        = filePath;
            _needsSave       = needsSave;

            var invisibleEditorManager = (IIntPtrReturningVsInvisibleEditorManager)serviceProvider.GetService(typeof(SVsInvisibleEditorManager));
            var vsProject          = TryGetProjectOfHierarchy(hierarchyOpt);
            var invisibleEditorPtr = IntPtr.Zero;

            Marshal.ThrowExceptionForHR(invisibleEditorManager.RegisterInvisibleEditor(filePath, vsProject, 0, null, out invisibleEditorPtr));

            try
            {
                _invisibleEditor = (IVsInvisibleEditor)Marshal.GetUniqueObjectForIUnknown(invisibleEditorPtr);

                var docDataPtr = IntPtr.Zero;
                Marshal.ThrowExceptionForHR(_invisibleEditor.GetDocData(fEnsureWritable: needsSave ? 1 : 0, riid: typeof(IVsTextLines).GUID, ppDocData: out docDataPtr));

                try
                {
                    var docData = Marshal.GetObjectForIUnknown(docDataPtr);
                    _vsTextLines = docData as IVsTextLines;
                    var vsTextBuffer = (IVsTextBuffer)docData;
                    var editorAdapterFactoryService = serviceProvider.GetMefService <IVsEditorAdaptersFactoryService>();
                    _buffer = editorAdapterFactoryService.GetDocumentBuffer(vsTextBuffer);
                    if (needsUndoDisabled)
                    {
                        Marshal.ThrowExceptionForHR(vsTextBuffer.GetUndoManager(out _manager));
                        Marshal.ThrowExceptionForHR((_manager as IVsUndoState).IsEnabled(out var isEnabled));
                        _needsUndoRestored = isEnabled != 0;
                        if (_needsUndoRestored)
                        {
                            _manager.DiscardFrom(null); // Discard the undo history for this document
                            _manager.Enable(0);         // Disable Undo for this document
                        }
                    }
                }
                finally
                {
                    Marshal.Release(docDataPtr);
                }
            }
            finally
            {
                // We need to clean up the extra reference we have, now that we have an RCW holding onto the object.
                Marshal.Release(invisibleEditorPtr);
            }
        }
Пример #8
0
        private string GetTextFromInvisibleEditor(IVsInvisibleEditor editor)
        {
            int hr = editor.GetDocData(0, typeof(IVsFullTextScanner).GUID, out IntPtr ptr);

            Marshal.ThrowExceptionForHR(hr);

            var fullText = (IVsFullTextScanner)Marshal.GetObjectForIUnknown(ptr);

            Marshal.Release(ptr);

            Marshal.ThrowExceptionForHR(fullText.OpenFullTextScan());
            Marshal.ThrowExceptionForHR(fullText.FullTextRead(out string text, out int length));
            Marshal.ThrowExceptionForHR(fullText.CloseFullTextScan());
            return(text);
        }
Пример #9
0
        /// <summary>
        ///     Get the preview temp file for a file extension.
        ///     If the temp file already exists, use that one.  Otherwise, create a new one.
        /// </summary>
        /// <param name="fileExtension">The file extension.</param>
        /// <returns>The preview temp file with file path, invisible editor and text buffer inforamtion.</returns>
        private PreviewTempFile GetPreviewTempFile(string fileExtension)
        {
            ArgumentValidation.CheckForNullReference(fileExtension, "fileExtension");

            PreviewTempFile tempFile = null;

            // If the temp file already exists, use that one.
            if (!_tempFiles.TryGetValue(fileExtension, out tempFile))
            {
                var failed = false;
                // Create a new preview temp file
                var tempFilePath = CreatePreviewTempFile(fileExtension);
                if (!File.Exists(tempFilePath))
                {
                    // Failed to create the temp file.
                    failed = true;
                }
                else
                {
                    // Open the file in invisible editor and get text buffer from it.
                    IVsInvisibleEditor invisibleEditor = null;
                    IVsTextLines       textBuffer      = null;
                    if (RdtManager.Instance.TryGetTextLinesAndInvisibleEditor(tempFilePath, out invisibleEditor, out textBuffer) &&
                        invisibleEditor != null &&
                        textBuffer != null)
                    {
                        // Temp file is opened in invisible editor, and we got the text buffer from it.
                        tempFile = new PreviewTempFile(tempFilePath, invisibleEditor, textBuffer);
                        _tempFiles.Add(fileExtension, tempFile);
                    }
                    else
                    {
                        failed = true;
                    }
                }
                if (failed)
                {
                    // Failed to get InvisibleEditor or TextBuffer for that file,
                    // throw exception.
                    throw new InvalidOperationException(
                              string.Format(
                                  CultureInfo.CurrentCulture,
                                  Resources.Exception_CannotGetTextBuffer,
                                  tempFilePath));
                }
            }
            return(tempFile);
        }
Пример #10
0
        public InvisibleEditor(IServiceProvider serviceProvider, string filePath, bool needsSave, bool needsUndoDisabled)
        {
            _serviceProvider = serviceProvider;
            _filePath = filePath;
            _needsSave = needsSave;

            var invisibleEditorManager = (IIntPtrReturningVsInvisibleEditorManager)serviceProvider.GetService(typeof(SVsInvisibleEditorManager));
            var invisibleEditorPtr = IntPtr.Zero;
            Marshal.ThrowExceptionForHR(invisibleEditorManager.RegisterInvisibleEditor(filePath, null, 0, null, out invisibleEditorPtr));

            try
            {
                _invisibleEditor = (IVsInvisibleEditor)Marshal.GetUniqueObjectForIUnknown(invisibleEditorPtr);

                var docDataPtr = IntPtr.Zero;
                Marshal.ThrowExceptionForHR(_invisibleEditor.GetDocData(fEnsureWritable: needsSave ? 1 : 0, riid: typeof(IVsTextLines).GUID, ppDocData: out docDataPtr));

                try
                {
                    var docData = Marshal.GetObjectForIUnknown(docDataPtr);
                    _vsTextLines = docData as IVsTextLines;
                    var vsTextBuffer = (IVsTextBuffer)docData;
                    var editorAdapterFactoryService = serviceProvider.GetMefService<IVsEditorAdaptersFactoryService>();
                    _buffer = editorAdapterFactoryService.GetDocumentBuffer(vsTextBuffer);
                    if (needsUndoDisabled)
                    {
                        Marshal.ThrowExceptionForHR(vsTextBuffer.GetUndoManager(out _manager));
                        int isEnabled;
                        Marshal.ThrowExceptionForHR((_manager as IVsUndoState).IsEnabled(out isEnabled));
                        _needsUndoRestored = isEnabled != 0;
                        if (_needsUndoRestored)
                        {
                            _manager.DiscardFrom(null); // Discard the undo history for this document
                            _manager.Enable(0); // Disable Undo for this document
                        }
                    }
                }
                finally
                {
                    Marshal.Release(docDataPtr);
                }
            }
            finally
            {
                // We need to clean up the extra reference we have, now that we have an RCW holding onto the object.
                Marshal.Release(invisibleEditorPtr);
            }
        }
Пример #11
0
        /// <summary>
        /// Closes the invisible editor and saves the underlying document as appropriate.
        /// </summary>
        public void Dispose()
        {
            AssertIsForeground();

            _buffer      = null;
            _vsTextLines = null !;

            try
            {
                if (_needsSave)
                {
                    // We need to tell this document to save before we get rid of the invisible editor. Otherwise,
                    // the invisible editor never actually makes the document go away. Check out CLockHolder::ReleaseEditLock
                    // in env\msenv\core\editmgr.cpp for details. We choose this particular technique for saving files
                    // since it's what the old cslangsvc.dll used.
                    var runningDocumentTable4 = (IVsRunningDocumentTable4)_serviceProvider.GetService(typeof(SVsRunningDocumentTable));

                    if (runningDocumentTable4.IsMonikerValid(_filePath))
                    {
                        var cookie = runningDocumentTable4.GetDocumentCookie(_filePath);
                        var runningDocumentTable = (IVsRunningDocumentTable)runningDocumentTable4;

                        // Old cslangsvc.dll requested not to add to MRU for, and I quote, "performance!". Makes sense not
                        // to include it in the MRU anyways.
                        ErrorHandler.ThrowOnFailure(runningDocumentTable.ModifyDocumentFlags(cookie, (uint)_VSRDTFLAGS.RDT_DontAddToMRU, fSet: 1));

                        runningDocumentTable.SaveDocuments((uint)__VSRDTSAVEOPTIONS.RDTSAVEOPT_SaveIfDirty, pHier: null, itemid: 0, docCookie: cookie);
                    }
                }

                if (_needsUndoRestored && _manager != null)
                {
                    _manager.Enable(1);
                    _manager = null;
                }

                // Clean up our RCW. This RCW is a unique RCW, so this is actually safe to do!
                Marshal.ReleaseComObject(_invisibleEditor);
                _invisibleEditor = null !;

                GC.SuppressFinalize(this);
            }
            catch (Exception ex) when(FatalError.ReportAndPropagate(ex, ErrorSeverity.Critical))  // critical severity, since this means we're not saving edited files
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Пример #12
0
        /// <summary>
        /// Cleans up an existing editor if we are about to put a new one in place, used to close down the old editor bits as well as
        /// nulling out any cached objects that we have that came from the now dead editor.
        /// </summary>
        private void ClearOldEditor()
        {
            if (this.codeWindow != null)
            {
                this.codeWindow.Close();
                this.codeWindow = null;
            }

            if (this.textView != null)
            {
                this.textView.CloseView();
                this.textView = null;
            }

            this.cachedEditorCommandTarget = null;
            this.cachedEditorFindTarget    = null;
            this.invisibleEditor           = null;
        }
Пример #13
0
        private IVsInvisibleEditor GetInvisibleEditor(string filePath)
        {
            if (_CurrentInvisibleEditor == null)
            {
                IVsHierarchy hierarchy;
                uint         itemID;
                IntPtr       docData;

                IVsInvisibleEditor editor;

                RunningDocumentTable.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, filePath,
                                                         out hierarchy, out itemID, out docData, out _docCookie);

                ErrorHandler.ThrowOnFailure(InvisibleEditorManager.RegisterInvisibleEditor(filePath, null, 1, null, out editor));
                _CurrentInvisibleEditor = editor;
            }
            return(_CurrentInvisibleEditor);
        }
Пример #14
0
            /// <summary>
            ///     Constructor
            /// </summary>
            /// <param name="fileFullPath">Full path of the file.</param>
            /// <param name="invisibleEditor">Invisible editor for that temp file.</param>
            /// <param name="textBuffer">Text buffer for that temp file.</param>
            public PreviewTempFile(string fileFullPath, IVsInvisibleEditor invisibleEditor, IVsTextLines textBuffer)
            {
                ArgumentValidation.CheckForEmptyString(fileFullPath, "fileFullPath");
                ArgumentValidation.CheckForNullReference(invisibleEditor, "invisibleEditor");
                ArgumentValidation.CheckForNullReference(textBuffer, "textBuffer");

                _tempFileFullPath = fileFullPath;
                InvisibleEditor = invisibleEditor;
                _textBuffer = textBuffer;
            }
Пример #15
0
        /// <summary>
        /// Closes the invisible editor and saves the underlying document as appropriate.
        /// </summary>
        public void Dispose()
        {
            _buffer = null;
            _vsTextLines = null;

            try
            {
                if (_needsSave)
                {
                    // We need to tell this document to save before we get rid of the invisible editor. Otherwise,
                    // the invisible editor never actually makes the document go away. Check out CLockHolder::ReleaseEditLock
                    // in env\msenv\core\editmgr.cpp for details. We choose this particular technique for saving files
                    // since it's what the old cslangsvc.dll used.
                    var runningDocumentTable4 = (IVsRunningDocumentTable4)_serviceProvider.GetService(typeof(SVsRunningDocumentTable));

                    if (runningDocumentTable4.IsMonikerValid(_filePath))
                    {
                        var cookie = runningDocumentTable4.GetDocumentCookie(_filePath);
                        var runningDocumentTable = (IVsRunningDocumentTable)runningDocumentTable4;

                        // Old cslangsvc.dll requested not to add to MRU for, and I quote, "performance!". Makes sense not
                        // to include it in the MRU anyways.
                        ErrorHandler.ThrowOnFailure(runningDocumentTable.ModifyDocumentFlags(cookie, (uint)_VSRDTFLAGS.RDT_DontAddToMRU, fSet: 1));

                        runningDocumentTable.SaveDocuments((uint)__VSRDTSAVEOPTIONS.RDTSAVEOPT_SaveIfDirty, pHier: null, itemid: 0, docCookie: cookie);
                    }
                }

                if (_needsUndoRestored && _manager != null)
                {
                    _manager.Enable(1);
                    _manager = null;
                }

                // Clean up our RCW. This RCW is a unqiue RCW, so this is actually safe to do!
                Marshal.ReleaseComObject(_invisibleEditor);
                _invisibleEditor = null;

                GC.SuppressFinalize(this);
            }
            catch (Exception ex) when(FatalError.Report(ex))
            {
            }
            }
        /// <summary>
        /// Cleans up an existing editor if we are about to put a new one in place, used to close down the old editor bits as well as
        /// nulling out any cached objects that we have that came from the now dead editor.
        /// </summary>
        internal void ClearEditor()
        {
            if (this.codeWindow != null)
            {
                this.codeWindow.Close();
                this.codeWindow = null;
            }

            if (this.textView != null)
            {
                this.textView.CloseView();
                this.textView = null;
            }

            this.cachedEditorCommandTarget = null;
            this.cachedEditorFindTarget = null;
            this.invisibleEditor = null;
        }
Пример #17
0
        private void CloseAndOpenInXMLEditor(string filePath)
        {
            IVsHierarchy ppHier       = null;
            uint         pitemid      = Microsoft.VisualStudio.VSConstants.VSITEMID_NIL;
            IntPtr       ppunkDocData = IntPtr.Zero;
            uint         pdwCookie    = Microsoft.VisualStudio.VSConstants.VSITEMID_NIL;

            try
            {
                // Get the IVsRunningDocumentTable interface and cast it to
                // IVsRunningDocumentTable2 interface.
                IVsRunningDocumentTable rdt =
                    GetService(typeof(SVsRunningDocumentTable))
                    as IVsRunningDocumentTable;
                IVsRunningDocumentTable2 rdt2 = rdt as IVsRunningDocumentTable2;

                // Find the opened document(.rc file) from the RDT.
                rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, filePath,
                                        out ppHier, out pitemid, out ppunkDocData, out pdwCookie);
                if (ppunkDocData != IntPtr.Zero)
                {
                    // Close the opened document.
                    Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(
                        rdt2.CloseDocuments((uint)__FRAMECLOSE.FRAMECLOSE_SaveIfDirty,
                                            null, pdwCookie));
                    ppunkDocData = IntPtr.Zero;
                }

                IVsInvisibleEditorManager spIEM;
                IVsInvisibleEditor        invisibleEditor = null;
                IVsWindowFrame            winFrame        = null;
                Guid logicalView = Microsoft.VisualStudio.VSConstants.LOGVIEWID_Primary;

                // Get the IVsInvisibleEditorManager interface.
                spIEM = (IVsInvisibleEditorManager)
                        GetService(typeof(IVsInvisibleEditorManager));
                // Register a invisible editor, then the specific document will be
                // loaded into the RDT.
                spIEM.RegisterInvisibleEditor(filePath, null,
                                              (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING,
                                              null, out invisibleEditor);

                // Get the IVsUIShellOpenDocument interface.
                IVsUIShellOpenDocument uiShellOpenDocument =
                    GetService(typeof(SVsUIShellOpenDocument))
                    as IVsUIShellOpenDocument;
                // Guid of the Microsoft XML editor
                Guid guidXMLEditor = new Guid("{FA3CD31E-987B-443A-9B81-186104E8DAC1}");
                rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, filePath,
                                        out ppHier, out pitemid, out ppunkDocData, out pdwCookie);
                // Open the document in XML editor.
                Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(
                    uiShellOpenDocument.OpenSpecificEditor((uint)0, filePath,
                                                           ref guidXMLEditor, "", ref logicalView, "XML Editor",
                                                           ppHier as IVsUIHierarchy, pitemid,
                                                           ppunkDocData, this, out winFrame));
                // Show the editor window.
                winFrame.Show();
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
            }
        }