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); }
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); }
private void Cleanup() { if (_docCookie != 0) { RunningDocumentTable.UnlockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, _docCookie); } _docCookie = 0; _CurrentInvisibleEditor = null; }
/// <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; }
private void Dispose(bool disposing) { if (!_disposed) { if (_invisibleEditor != null && disposing) { Marshal.ReleaseComObject(_invisibleEditor); _invisibleEditor = null; } _disposed = true; } }
/// <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); } }
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); }
/// <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); }
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); } }
/// <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; } }
/// <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; }
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); }
/// <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; }
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); } }