Quantcast
Channel: Visual Studio Integrate forum
Viewing all articles
Browse latest Browse all 4410

Reacting on file changed outside IDE

$
0
0

I use a combination of IVsFileChangeEvents and IVsFileChangeEx to monitor, whether file edited in my editor extension was modified outside the IDE. However, for some unknown reason, I get the notification twice - thus resulting in asking user for reload twice.

The implementation of FilesChanged looks like the following:

        public int FilesChanged(uint cChanges, string[] rgpszFile, uint[] rggrfChange) {

            foreach (var file in rgpszFile)
            {
                if (file.ToLowerInvariant() == documentPath.ToLowerInvariant()) {

                    System.Diagnostics.Debug.WriteLine("File changed - asking for reload");

                    if (MessageBox.Show("The file {0} was changed outside the editor. Do you want to reload it?".FillWith(file), "MyEditor", 
                        MessageBoxButton.YesNo, 
                        MessageBoxImage.Question) == MessageBoxResult.Yes) {

                        fileChangeEx.IgnoreFile(fileCookie, null, 1);

                        // Unloading document
                        DoCloseDocument();

                        // Loading document
                        DoLoadDocument(file);

                        fileChangeEx.SyncFile(documentPath);
                        fileChangeEx.IgnoreFile(fileCookie, null, 0);
                    }
                }
            }
            return VSConstants.S_OK;
        }


What should I do to receive the event only once? I test this code by saving the same file in Notepad++.

This is a log from SysInternals' ProcMon:

09:05:21,2272369	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:21,2273658	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:21,2275512	notepad++.exe	256	QueryDirectory	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Filter: settings.definition, 1: settings.definition
09:05:28,7692878	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:28,7694244	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:28,7696066	notepad++.exe	256	QueryDirectory	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Filter: settings.definition, 1: settings.definition
09:05:44,0463636	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:46,4087520	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:46,4088700	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:46,4089646	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 08:50:27, ChangeTime: 2014-05-23 08:50:27, AllocationSize: 4 096, EndOfFile: 1 740, FileAttributes: A
09:05:46,4090631	notepad++.exe	256	CreateFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Desired Access: Generic Write, Read Attributes, Dis, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: 0, OpenResult: Overwritten
09:05:46,4100654	notepad++.exe	256	WriteFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Offset: 0, Length: 1 742, Priority: Normal
09:05:46,4101850	notepad++.exe	256	CloseFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	
09:05:46,4102751	devenv.exe	6884	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:05:46,4103088	MsMpEng.exe	956	CreateFileMapping	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	FILE LOCKED WITH WRITERS	SyncType: SyncTypeCreateSection, PageProtection: 
09:05:46,4103322	MsMpEng.exe	956	QueryStandardInformationFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	AllocationSize: 4 096, EndOfFile: 1 742, NumberOfLinks: 1, DeletePending: False, Directory: False
09:05:46,4144664	notepad++.exe	256	QueryDirectory	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Filter: settings.definition, 1: settings.definition
09:05:46,4160238	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:05:46,4172362	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:05:46,4173472	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:05:46,4175063	notepad++.exe	256	QueryDirectory	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Filter: settings.definition, 1: settings.definition
09:05:46,4178437	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:05:46,4185672	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:05:46,4186404	devenv.exe	6884	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:06:06,8788282	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:06:06,8789555	notepad++.exe	256	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:06:06,8791373	notepad++.exe	256	QueryDirectory	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Filter: settings.definition, 1: settings.definition
09:06:50,6465883	devenv.exe	6884	CreateFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Desired Access: Generic Read, Dis, Options: Synchronous IO Non-Alert, Non-Directory File, Open No Recall, Attributes: n/a, ShareMode: Read, AllocationSize: n/a, OpenResult: Opened
09:06:50,6466482	devenv.exe	6884	QueryStandardInformationFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	AllocationSize: 4 096, EndOfFile: 1 742, NumberOfLinks: 1, DeletePending: False, Directory: False
09:06:50,6466665	devenv.exe	6884	ReadFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Offset: 0, Length: 1 742, Priority: Normal
09:06:50,6467374	devenv.exe	6884	ReadFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	END OF FILE	Offset: 1 742, Length: 4 096
09:06:50,6469314	devenv.exe	6884	CloseFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	
09:06:50,6477175	devenv.exe	6884	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:06:50,6963339	devenv.exe	6884	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:07:02,3340501	devenv.exe	6884	CreateFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Desired Access: Generic Read, Dis, Options: Synchronous IO Non-Alert, Non-Directory File, Open No Recall, Attributes: n/a, ShareMode: Read, AllocationSize: n/a, OpenResult: Opened
09:07:02,3341050	devenv.exe	6884	QueryStandardInformationFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	AllocationSize: 4 096, EndOfFile: 1 742, NumberOfLinks: 1, DeletePending: False, Directory: False
09:07:02,3341200	devenv.exe	6884	ReadFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	Offset: 0, Length: 1 742, Priority: Normal
09:07:02,3341887	devenv.exe	6884	ReadFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	END OF FILE	Offset: 1 742, Length: 4 096
09:07:02,3343792	devenv.exe	6884	CloseFile	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	
09:07:02,3351733	devenv.exe	6884	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A
09:07:02,3626280	devenv.exe	6884	QueryOpen	D:\VS Projects\Temporary\WindowsFormsApplication1\WindowsFormsApplication1\NewFolder1\settings.definition	SUCCESS	CreationTime: 2014-05-21 13:08:34, LastAccessTime: 2014-05-21 13:08:34, LastWriteTime: 2014-05-23 09:05:46, ChangeTime: 2014-05-23 09:05:46, AllocationSize: 4 096, EndOfFile: 1 742, FileAttributes: A

It seems like the MessageBox.Show call is the main reason for the second notification. The call stack looks like the following:

>	MyAssembly.dll!MyClass.FilesChanged(uint cChanges = 1, string[] rgpszFile = {string[1]}, uint[] rggrfChange = {uint[1]}) Line 284	C#
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.FileChangeSubscription.Notify.AnonymousMethod__0()	Unknown
 	Microsoft.VisualStudio.Shell.12.0.dll!Microsoft.VisualStudio.ErrorHandler.CallWithCOMConvention(System.Func<int> method, bool reportError = false, bool setShellErrorInfo = true)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.FileChangeSubscription.Notify(Microsoft.VisualStudio.Shell.Interop._VSFILECHANGEFLAGS changes)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.FileChangeSubscription.Notify(System.IO.WatcherChangeTypes changeTypes, Microsoft.VisualStudio.Services.FileProperties props)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.FileWatcher.Notify(Microsoft.VisualStudio.Services.ChangeStreamDigest digest)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.DirectoryWatcher.ProcessFileChanges(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,Microsoft.VisualStudio.Services.ChangeStreamDigest>> digests, int depth)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.DirectoryWatcher.ProcessChanges(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,Microsoft.VisualStudio.Services.ChangeStreamDigest>> digests = Count = 1, int depth = 3)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.DirectoryWatcher.ProcessChanges(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,Microsoft.VisualStudio.Services.ChangeStreamDigest>> digests = Count = 1, int depth = 2)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.DirectoryWatcher.ProcessChanges(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,Microsoft.VisualStudio.Services.ChangeStreamDigest>> digests = {Microsoft.Internal.VisualStudio.PlatformUI.HybridDictionary<string,Microsoft.VisualStudio.Services.ChangeStreamDigest>}, int depth = 1)	Unknown
 	Microsoft.VisualStudio.Shell.UI.Internal.dll!Microsoft.VisualStudio.Services.DirectoryWatcher.OnChangedAsync()	Unknown
 	WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)	Unknown
 	WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate method, object args, int numArgs, System.Delegate catchHandler = null)	Unknown
 	WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl()	Unknown
 	WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state)	Unknown
 	mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)	Unknown
 	mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)	Unknown
 	mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)	Unknown
 	WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke()	Unknown
 	WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue()	Unknown
 	WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)	Unknown
 	WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd = 264738, int msg = 49778, System.IntPtr wParam = 0, System.IntPtr lParam = 0, ref bool handled = false)	Unknown
 	WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)	Unknown
 	WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)	Unknown
 	WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate method, object args, int numArgs, System.Delegate catchHandler = null)	Unknown
 	WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)	Unknown
 	WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd = 264738, int msg = 49778, System.IntPtr wParam = 0, System.IntPtr lParam = 0)	Unknown
 	[Native to Managed Transition]	
 	[Managed to Native Transition]	
 	PresentationFramework.dll!System.Windows.MessageBox.ShowCore(System.IntPtr owner, string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon, System.Windows.MessageBoxResult defaultResult, System.Windows.MessageBoxOptions options)	Unknown
 	PresentationFramework.dll!System.Windows.MessageBox.Show(string messageBoxText, string caption, System.Windows.MessageBoxButton button, System.Windows.MessageBoxImage icon)	Unknown
 	MyAssembly.dll!MyClass.FilesChanged(uint cChanges = 1, string[] rgpszFile = {string[1]}, uint[] rggrfChange = {uint[1]}) Line 290	C#




Viewing all articles
Browse latest Browse all 4410

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>