public IDisposable MarkIgnoreFile(string path) { ThreadHelper.ThrowIfNotOnUIThread(); if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } IVsFileChangeEx change = GetService <IVsFileChangeEx>(typeof(SVsFileChangeEx)); if (change != null) { Marshal.ThrowExceptionForHR(change.IgnoreFile(0, path, 1)); return(new DelegateRunner( delegate() { ThreadHelper.ThrowIfNotOnUIThread(); change.SyncFile(path); change.IgnoreFile(0, path, 0); })); } else { return(null); } }
private IDisposable MarkIgnoreRecursive(string newDir) { ThreadHelper.ThrowIfNotOnUIThread(); IAnkhOpenDocumentTracker dt = GetService <IAnkhOpenDocumentTracker>(); IVsFileChangeEx change = GetService <IVsFileChangeEx>(typeof(SVsFileChangeEx)); if (dt == null || change == null) { return(null); } ICollection <string> files = dt.GetDocumentsBelow(newDir); if (files == null || files.Count == 0) { return(null); } foreach (string file in files) { Marshal.ThrowExceptionForHR(change.IgnoreFile(0, file, 1)); } return(new DelegateRunner( delegate() { ThreadHelper.ThrowIfNotOnUIThread(); foreach (string file in files) { change.SyncFile(file); change.IgnoreFile(0, file, 0); } })); }
/// <summary> /// In this function we suspend receiving file change events for /// a file or we reinstate a previously suspended file depending /// on the value of the given fSuspend flag. /// </summary> /// <param name="pszFileName">File name string</param> /// <param name="fSuspend">TRUE indicates that the events needs to be suspended</param> /// <returns></returns> private int SuspendFileChangeNotification(string pszFileName, int fSuspend) { Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "\t **** Inside SuspendFileChangeNotification ****")); if (null == vsFileChangeEx) { vsFileChangeEx = (IVsFileChangeEx)GetService(typeof(SVsFileChangeEx)); } if (null == vsFileChangeEx) { return(VSConstants.E_UNEXPECTED); } if (0 == fSuspend) { // we are transitioning from suspended to non-suspended state - so force a // sync first to avoid asynchronous notifications of our own change if (vsFileChangeEx.SyncFile(pszFileName) == VSConstants.E_FAIL) { return(VSConstants.E_FAIL); } } //If we use the VSCOOKIE parameter to specify the file, then pszMkDocument parameter //must be set to a null reference and vice versa return(vsFileChangeEx.IgnoreFile(vsFileChangeCookie, null, fSuspend)); }
public void Resume() { if (!mIsSuspending || mPersistDocData == null) { return; } if (mPersistDocData != null && mReloadDocument) { mPersistDocData.ReloadDocData(0); } IVsFileChangeEx fileChange = mSite.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx; if (fileChange == null) { return; } mIsSuspending = false; ErrorHandler.ThrowOnFailure(fileChange.SyncFile(mDocumentFileName)); ErrorHandler.ThrowOnFailure(fileChange.IgnoreFile(0, mDocumentFileName, 0)); if (mFileChangeControl != null) { ErrorHandler.ThrowOnFailure(mFileChangeControl.IgnoreFileChanges(0)); } }
/// <summary> /// Resumes file change notifications to the environment for the wrapped file. /// </summary> public void Resume() { if (!this.suspended) { return; } // Get the environment's change notifier. IVsFileChangeEx changeNotifier = Package.Instance.Context.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx; Tracer.WriteLineIf(classType, "Resume", Tracer.Level.Warning, changeNotifier == null, "Could not get an instance of the IVsChangeEx interface."); if (changeNotifier != null) { // Tell the environment to resume sending change notifications for the file. int hr = changeNotifier.IgnoreFile(0, this.FilePath, ResumeNotification); Tracer.WriteLineIf(classType, "Resume", Tracer.Level.Warning, NativeMethods.Failed(hr), "Could not tell the environment to resume file change notifications to '{0}': Hr=0x{1:x}", this.FilePath, hr); } // Tell the environment to resume sending change notifications to editors. if (this.docDataFileChangeControl != null) { int hr = this.docDataFileChangeControl.IgnoreFileChanges(ResumeNotification); Tracer.WriteLineIf(classType, "Resume", Tracer.Level.Warning, NativeMethods.Failed(hr), "Could not tell the environment to resume file change notifications to editors of file '{0}': Hr=0x{1:x}", this.FilePath, hr); this.docDataFileChangeControl = null; } // At this point we can consider ourself resumed. this.suspended = false; Tracer.WriteLineVerbose(classType, "Resume", "Resumed file change notifications for '{0}'.", this.FilePath); }
public IDisposable SuppressChangeNotifications(string filePath) { IVsFileChangeEx service = (IVsFileChangeEx)this.VisualStudio.ServiceProvider.GetService(typeof(IVsFileChangeEx)); Marshal.ThrowExceptionForHR(service.IgnoreFile(0, filePath, 1)); return(new EditorIntegration.NotificationActivator(this, filePath)); }
public void GetLatest(string item) { Workspace workspace = this.GetWorkspace(item); if (workspace == null) { return; } string serverPath = workspace.TryGetServerItemForLocalItem(item); if (serverPath != null) { using (UIHost.GetWaitCursor()) { IVsFileChangeEx fce = serviceProvider.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx; int hr = 0; if (fce != null) { try { // Ignore file changes, so there is no Reload dialog hr = fce.IgnoreFile(VSConstants.VSCOOKIE_NIL, item, 1); Debug.Assert(hr == VSConstants.S_OK); GetRequest getRequest = new GetRequest(serverPath, RecursionType.None, VersionSpec.Latest); GetStatus status = workspace.Get(getRequest, GetOptions.None, null, null); if (status != null && status.NumConflicts > 0) { // Trigger resolve conflicts tool window if there are any, to be consistent with solution explorer this.dte.ExecuteCommand("File.TfsResumeConflictResolution"); } } finally { // Sync file so that file changes do not trigger events later when we un-ignore hr = fce.SyncFile(item); Debug.Assert(hr == VSConstants.S_OK); hr = fce.IgnoreFile(VSConstants.VSCOOKIE_NIL, item, 0); Debug.Assert(hr == VSConstants.S_OK); } } } } }
public SccDocumentLock(OpenDocumentTracker tracker, HybridCollection <string> locked, HybridCollection <string> ignoring, HybridCollection <string> readOnly) { ThreadHelper.ThrowIfNotOnUIThread(); if (tracker == null) { throw new ArgumentNullException("tracker"); } else if (locked == null) { throw new ArgumentNullException("locked"); } else if (ignoring == null) { throw new ArgumentNullException("ignoring"); } else if (readOnly == null) { throw new ArgumentNullException("readOnly"); } _tracker = tracker; _locked = locked; _ignoring = ignoring; _readonly = readOnly; _fsIgnored = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); _changedPaths = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); _monitor = new Dictionary <uint, string>(); _altMonitor = new Dictionary <string, FileInfo>(); _change = tracker.GetService <IVsFileChangeEx>(typeof(SVsFileChangeEx)); foreach (string file in locked) { // This files auto reload could not be suspended by calling Ignore on the document // We must therefore stop posting messages to it by stopping it in the change monitor // But to be able to tell if there are changes.. We keep some stats ourselves if (!ignoring.Contains(file) && VSErr.Succeeded(_change.IgnoreFile(0, file, 1))) { _fsIgnored.Add(file); FileInfo info = new FileInfo(file); info.Refresh(); if (info.Exists) { GC.KeepAlive(info.LastWriteTime); GC.KeepAlive(info.CreationTime); GC.KeepAlive(info.Length); } _altMonitor.Add(file, info); } } }
/// <summary> /// Turns on/off file ignore option. When file changes are ignored, VS doesn't display a dialog asking user about reloading the changes. /// </summary> public static void SetIgnoreFileChanges(string path, bool ignore) { if (string.IsNullOrEmpty(path)) { return; } IVsHierarchy ppHier; uint pitemid; IntPtr pPunkDocData; uint pdwCookie; int hr = IVsRunningDocumentTable.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, path, out ppHier, out pitemid, out pPunkDocData, out pdwCookie); Marshal.ThrowExceptionForHR(hr); if (pPunkDocData != IntPtr.Zero) { IVsFileChangeEx fileChange = (IVsFileChangeEx)Package.GetGlobalService(typeof(SVsFileChangeEx)); if (fileChange == null) { throw new InvalidOperationException("Cannot consume IVsFileChangeEx."); } IVsDocDataFileChangeControl changeControl = (IVsDocDataFileChangeControl)Marshal.GetObjectForIUnknown(pPunkDocData); if (ignore) { hr = fileChange.IgnoreFile(0, path, 1); Marshal.ThrowExceptionForHR(hr); hr = changeControl.IgnoreFileChanges(1); } else { hr = fileChange.IgnoreFile(0, path, 0); Marshal.ThrowExceptionForHR(hr); hr = changeControl.IgnoreFileChanges(0); } } }
private void ResumeChangeNotifications(string filePath) { IVsFileChangeEx service = (IVsFileChangeEx)this.VisualStudio.ServiceProvider.GetService(typeof(IVsFileChangeEx)); try { Marshal.ThrowExceptionForHR(service.SyncFile(filePath)); } finally { Marshal.ThrowExceptionForHR(service.IgnoreFile(0, filePath, 0)); } }
void StopMonitor() { ThreadHelper.ThrowIfNotOnUIThread(); // Stop monitoring foreach (uint v in _monitor.Keys) { _change.UnadviseFileChange(v); } _monitor.Clear(); foreach (string path in _fsIgnored) { _change.SyncFile(path); _change.IgnoreFile(0, path, 0); } _fsIgnored.Clear(); // Sync all files for the last time // to make sure they are not reloaded for old changes after disposing foreach (string path in _locked) { _change.SyncFile(path); } _locked.Clear(); foreach (string path in _readonly) { SccDocumentData dd; if (_tracker._docMap.TryGetValue(path, out dd)) { dd.SetReadOnly(false); } } _readonly.Clear(); foreach (string path in _ignoring) { SccDocumentData dd; if (_tracker._docMap.TryGetValue(path, out dd)) { dd.IgnoreFileChanges(false); } } _ignoring.Clear(); }
public IDisposable SuppressChangeNotifications(string filePath) { // In general we want to turn off notifications for a file if NuGet is changing it externally, this will avoid the // 'file has changed, would you like to reload' dialog. // // See: http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivsfilechangeex.syncfile(v=vs.110).aspx // for an example. IVsFileChangeEx fileChangeService = (IVsFileChangeEx)visualStudio.ServiceProvider.GetService(typeof(IVsFileChangeEx)); // This is a COM interface that wants the Win32 TRUE, which is why the third value is 1. int hr = fileChangeService.IgnoreFile(0u, filePath, 1); Marshal.ThrowExceptionForHR(hr); return(new NotificationActivator(this, filePath)); }
public void Ignore(string filepath, bool ignore, bool prelowered) { if (fileChangeEx != null && !String.IsNullOrEmpty(filepath)) { if (!prelowered) { filepath = filepath.ToLower(); } uint cookie; lock (eventCookies) { if (eventCookies.TryGetValue(filepath, out cookie)) { ErrorHandler.ThrowOnFailure(fileChangeEx.IgnoreFile(cookie, filepath, (ignore) ? 0 : 1)); MyPackage.OutputGeneral("Ignoring \"" + filepath + "\""); } } } }
/// <summary> /// Suspends any file change notifications to the environment for the wrapped file in /// preparation for a multi-stage file operation such as a rename. /// </summary> public void Suspend() { // We only want to suspend once. if (this.suspended) { return; } // Get the environment's change notifier. IVsFileChangeEx changeNotifier = Package.Instance.Context.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx; if (changeNotifier == null) { Tracer.WriteLineWarning(classType, "Suspend", "Could not get an instance of the IVsChangeEx interface."); return; } // Tell the environment to stop sending change notifications for the file. int hr = changeNotifier.IgnoreFile(0, this.FilePath, IgnoreChanges); Tracer.WriteLineIf(classType, "Suspend", Tracer.Level.Warning, NativeMethods.Failed(hr), "Could not tell the environment to ignore file changes to '{0}': Hr=0x{1:x}", this.FilePath, hr); NativeMethods.ThrowOnFailure(hr); // Get the IVsDocDataFileChangeControl interface from the DocumentData. We need this // to suspend file change notifications to all editors. DocumentInfo docInfo = Package.Instance.Context.RunningDocumentTable.FindByPath(this.FilePath); if (docInfo != null) { this.docDataFileChangeControl = docInfo.DocumentData as IVsDocDataFileChangeControl; if (this.docDataFileChangeControl != null) { hr = this.docDataFileChangeControl.IgnoreFileChanges(IgnoreChanges); NativeMethods.ThrowOnFailure(hr); } } // At this point we can consider ourself suspended. this.suspended = true; Tracer.WriteLineVerbose(classType, "Suspend", "Suspended file change notifications for '{0}'.", this.FilePath); }
private void ResumeChangeNotifications(string filePath) { IVsFileChangeEx fileChangeService = (IVsFileChangeEx)visualStudio.ServiceProvider.GetService(typeof(IVsFileChangeEx)); int hr; try { // We need to call sync to 'flush' events that have piled up for the file, this prevents a notification // from being delivered after we turn notifications back on. hr = fileChangeService.SyncFile(filePath); Marshal.ThrowExceptionForHR(hr); } finally { // We want to turn notifications back on if the sync fails for some reason // // This is a COM interface that wants the Win32 FALSE, which is why the third value is 0. hr = fileChangeService.IgnoreFile(0u, filePath, 0); Marshal.ThrowExceptionForHR(hr); } }
public void Suspend() { if (mIsSuspending) { return; } mDocData = IntPtr.Zero; try { IVsRunningDocumentTable rdt = mSite.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable; if (rdt == null) { return; } ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_NoLock, mDocumentFileName, out IVsHierarchy hierarchy, out uint itemId, out mDocData, out uint docCookie)); if ((docCookie == (uint)ShellConstants.VSDOCCOOKIE_NIL) || mDocData == IntPtr.Zero) { return; } IVsFileChangeEx fileChange = mSite.GetService(typeof(SVsFileChangeEx)) as IVsFileChangeEx; if (fileChange == null) { return; } mIsSuspending = true; ErrorHandler.ThrowOnFailure(fileChange.IgnoreFile(0, mDocumentFileName, 1)); if (mDocData == IntPtr.Zero) { return; } mPersistDocData = null; object unknown = Marshal.GetObjectForIUnknown(mDocData); if (!(unknown is IVsPersistDocData)) { return; } mPersistDocData = (IVsPersistDocData)unknown; if (!(mPersistDocData is IVsDocDataFileChangeControl)) { return; } mFileChangeControl = (IVsDocDataFileChangeControl)mPersistDocData; if (mFileChangeControl != null) { ErrorHandler.ThrowOnFailure(mFileChangeControl.IgnoreFileChanges(1)); } } catch (InvalidCastException e) { Trace.WriteLine("Exception" + e.Message); } finally { if (mDocData != IntPtr.Zero) { Marshal.Release(mDocData); } } }
public SccDocumentLock(OpenDocumentTracker tracker, HybridCollection<string> locked, HybridCollection<string> ignoring, HybridCollection<string> readOnly) { if (tracker == null) throw new ArgumentNullException("tracker"); else if (locked == null) throw new ArgumentNullException("locked"); else if (ignoring == null) throw new ArgumentNullException("ignoring"); else if (readOnly == null) throw new ArgumentNullException("readOnly"); _tracker = tracker; _locked = locked; _ignoring = ignoring; _readonly = readOnly; _fsIgnored = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); _changedPaths = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); _monitor = new Dictionary<uint, string>(); _altMonitor = new Dictionary<string, FileInfo>(); _change = tracker.GetService<IVsFileChangeEx>(typeof(SVsFileChangeEx)); foreach (string file in locked) { // This files auto reload could not be suspended by calling Ignore on the document // We must therefore stop posting messages to it by stopping it in the change monitor // But to be able to tell if there are changes.. We keep some stats ourselves if (!ignoring.Contains(file) && ErrorHandler.Succeeded(_change.IgnoreFile(0, file, 1))) { _fsIgnored.Add(file); FileInfo info = new FileInfo(file); info.Refresh(); if (info.Exists) { GC.KeepAlive(info.LastWriteTime); GC.KeepAlive(info.CreationTime); GC.KeepAlive(info.Length); } _altMonitor.Add(file, info); } } }