예제 #1
0
        public async Task FilesChanged_CallsProjectToReload(_VSFILECHANGEFLAGS flags)
        {
            string projectFile = @"c:\temp\project1.csproj";
            var    spMock      = new IServiceProviderMoq();

            spMock.AddService(typeof(IVsFileChangeEx), typeof(SVsFileChangeEx), IVsFileChangeExFactory.CreateWithAdviseUnadviseFileChange(100));
            spMock.AddService(typeof(IVsSolution), typeof(SVsSolution), IVsSolutionFactory.CreateWithAdviseUnadviseSolutionEvents(150));

            var rlm = new ProjectReloadManager(IProjectThreadingServiceFactory.Create(), spMock, IUserNotificationServicesFactory.ImplementReportErrorInfo(), new Mock <IDialogServices>().Object);

            var reloadableProjectMock = new Mock <IReloadableProject>(MockBehavior.Strict);

            reloadableProjectMock.Setup(x => x.ProjectFile).Returns(projectFile);
            reloadableProjectMock.Setup(x => x.ReloadProjectAsync()).Returns(Task.FromResult(ProjectReloadResult.ReloadCompleted));

            await rlm.RegisterProjectAsync(reloadableProjectMock.Object);

            Assert.Equal <int>(1, rlm.RegisteredProjects.Count);
            // Shorten the normal delay so unit tests run faster
            ((TaskDelayScheduler)rlm.ReloadDelayScheduler).TaskDelayTime = TimeSpan.FromMilliseconds(20);

            rlm.FilesChanged(1, new string[1] {
                projectFile
            }, new uint[1] {
                (uint)flags
            });
            await rlm.ReloadDelayScheduler.LatestScheduledTask;

            reloadableProjectMock.VerifyAll();
        }
예제 #2
0
 public FileChangeTracker(IVsFileChangeEx fileChangeService, string filePath, _VSFILECHANGEFLAGS fileChangeFlags = DefaultFileChangeFlags)
 {
     _fileChangeService = fileChangeService;
     _filePath          = filePath;
     _fileChangeFlags   = fileChangeFlags;
     _fileChangeCookie  = s_none;
 }
예제 #3
0
        public Task <uint> AdviseFileChangeAsync(string filename, _VSFILECHANGEFLAGS filter, IVsFreeThreadedFileChangeEvents2 sink, CancellationToken cancellationToken = default)
        {
            _uniqueFilesWatched.Add(filename);

            uint cookie = _lastCookie++;

            _watchedFiles.Add(cookie, filename);
            return(System.Threading.Tasks.Task.FromResult(cookie));
        }
예제 #4
0
            private WatcherOperation(Kind kind)
            {
                Contract.ThrowIfFalse(kind is Kind.None);
                _kind = kind;

                // Other watching fields are not used for this kind
                _directory       = null !;
                _filter          = null;
                _fileChangeFlags = 0;
                _sink            = null !;
                _cookies         = null !;
                _token           = null !;
                _tokens          = null !;
            }
예제 #5
0
            private WatcherOperation(Kind kind, IEnumerable <Context.FileWatchingToken> tokens)
            {
                Contract.ThrowIfFalse(kind is Kind.UnwatchFiles);
                _kind = kind;

                _tokens = tokens;

                // Other watching fields are not used for this kind
                _directory       = null !;
                _filter          = null;
                _fileChangeFlags = 0;
                _sink            = null !;
                _cookies         = null !;
                _token           = null !;
            }
예제 #6
0
            private WatcherOperation(Kind kind, string path, _VSFILECHANGEFLAGS fileChangeFlags, IVsFreeThreadedFileChangeEvents2 sink, Context.FileWatchingToken token)
            {
                Contract.ThrowIfFalse(kind is Kind.WatchFile);
                _kind = kind;

                _directory       = path;
                _fileChangeFlags = fileChangeFlags;
                _sink            = sink;
                _token           = token;

                // Other watching fields are not used for this kind
                _filter  = null;
                _cookies = null !;
                _tokens  = null !;
            }
예제 #7
0
            private WatcherOperation(Kind kind, string directory, string?filter, IVsFreeThreadedFileChangeEvents2 sink, List <uint> cookies)
            {
                Contract.ThrowIfFalse(kind is Kind.WatchDirectory);
                _kind = kind;

                _directory = directory;
                _filter    = filter;
                _sink      = sink;
                _cookies   = cookies;

                // Other watching fields are not used for this kind
                _fileChangeFlags = 0;
                _token           = null !;
                _tokens          = null !;
            }
        int IVsFileChangeEvents.FilesChanged(uint countChanges, string[] rgpszFile, uint[] rggrfChange)
        {
            lock (this.changedFiles)
            {
                for (int i = 0; i < countChanges; i++)
                {
                    string             fileName = rgpszFile[i];
                    _VSFILECHANGEFLAGS flags    = (_VSFILECHANGEFLAGS)rggrfChange[i];
                    bool exists = !flags.HasFlag(_VSFILECHANGEFLAGS.VSFILECHG_Del);
                    this.changedFiles[fileName] = exists;
                }
            }

            return(VSConstants.S_OK);
        }
        public void Add(string fileName)
        {
            uint cookie;

            if (!this.cookies.TryGetValue(fileName, out cookie))
            {
                // We have to handle Adds in case someone deletes a file and then recreates it.
                const _VSFILECHANGEFLAGS Flags = _VSFILECHANGEFLAGS.VSFILECHG_Add
                                                 | _VSFILECHANGEFLAGS.VSFILECHG_Del
                                                 | _VSFILECHANGEFLAGS.VSFILECHG_Size
                                                 | _VSFILECHANGEFLAGS.VSFILECHG_Time;
                int hr = this.fileChangeService.AdviseFileChange(fileName, (uint)Flags, this, out cookie);

                // AdviseFileChange will fail with an E_INVALIDARG result if fileName isn't a valid file name
                // (e.g., if it's a moniker like RDT_PROJ_MK::{42D00E44-28B8-4CAA-950E-909D5273945D}).
                if (ErrorHandler.Succeeded(hr))
                {
                    this.cookies.Add(fileName, cookie);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Notifies clients of changes made to one or more files.
        /// </summary>
        /// <param name="numberOfFilesChanged">
        /// Number of files changed.
        /// </param>
        /// <param name="files">
        /// Array of file names.
        /// </param>
        /// <param name="typesOfChange">
        /// Array of flags indicating the type of changes. <see cref="_VSFILECHANGEFLAGS" />.
        public int FilesChanged(uint numberOfFilesChanged, string[] files, uint[] changeTypes)
        {
            // Go over each file and treat the change appropriately
            for (int i = 0; i < files.Length; i++)
            {
                string             path   = files[i];
                _VSFILECHANGEFLAGS change = (_VSFILECHANGEFLAGS)changeTypes[i];

                // _VSFILECHANGEFLAGS.VSFILECHG_Add is handled by DirectoryChanged
                // Only handle _VSFILECHANGEFLAGS.VSFILECHG_Del here
                if (change == _VSFILECHANGEFLAGS.VSFILECHG_Del)
                {
                    MacroFSNode node = MacroFSNode.FindNodeFromFullPath(path);
                    if (node != null)
                    {
                        node.Delete();
                    }
                }
            }

            return(VSConstants.S_OK);
        }
예제 #11
0
 public static WatcherOperation WatchFile(string path, _VSFILECHANGEFLAGS fileChangeFlags, IVsFreeThreadedFileChangeEvents2 sink, Context.FileWatchingToken token)
 => new(Kind.WatchFile, path, fileChangeFlags, sink, token);
        public void Should_trigger_save_action_when_a_watched_file_is_saved(_VSFILECHANGEFLAGS changeFlag)
        {
            var file = new[] {"file"};
            A.CallTo(() => this.fileMonitor.IsMonitoredFile("file")).Returns(true);
            this.eventListener.Initialize(A.Dummy<ISolutionProject>(), A.Dummy<ActionConfiguration>());

            this.eventListener.FilesChanged(1, file, new [] { (uint)changeFlag });

            A.CallTo(() => this.actionFactory.Create(A<ActionConfiguration>._, A<IEnumerable<string>>._)).MustHaveHappened();
        }
예제 #13
0
 /// <summary>
 /// Constructs a new event args.
 /// </summary>
 /// <param name="fileName">File name that was changed on disk.</param>
 /// <param name="id">The item id of the file that was changed on disk.</param>
 /*internal, but public for FSharp.Project.dll*/ public FileChangedOnDiskEventArgs(string fileName, uint id, _VSFILECHANGEFLAGS flag)
 {
     this.fileName       = fileName;
     this.itemID         = id;
     this.fileChangeFlag = flag;
 }
예제 #14
0
 public FolderChangedEventArgs(string folderName, string fileName, _VSFILECHANGEFLAGS fileChangeFlag)
 {
     this.FolderName     = folderName;
     this.FileName       = fileName;
     this.FileChangeFlag = fileChangeFlag;
 }
 /// <summary>
 /// Constructs a new event args.
 /// </summary>
 /// <param name="fileName">File name that was changed on disk.</param>
 /// <param name="id">The item id of the file that was changed on disk.</param>
 public FileChangedOnDiskEventArgs(string fileName, uint id, _VSFILECHANGEFLAGS flag)
 {
     this.fileName = fileName;
     this.itemID = id;
     this.fileChangeFlag = flag;
 }
예제 #16
0
 /// <summary>
 /// Constructs a new event args.
 /// </summary>
 /// <param name="fileName">File name that was changed on disk.</param>
 /// <param name="id">The item id of the file that was changed on disk.</param>
 internal FileChangedOnDiskEventArgs(string fileName, uint id, _VSFILECHANGEFLAGS flag)
 {
     this.fileName       = fileName;
     this.itemID         = id;
     this.fileChangeFlag = flag;
 }
예제 #17
0
 /// <summary>
 /// Constructs a new event args.
 /// </summary>
 /// <param name="fileName">File name that was changed on disk.</param>
 /// <param name="id">The item id of the file that was changed on disk.</param>
 internal FileChangedOnDiskEventArgs(string fileName, _VSFILECHANGEFLAGS flag)
 {
     this.FileName   = fileName;
     this.FileChange = ConvertVSFILECHANGEFLAGS((uint)flag);
 }