/// <summary> /// Returns whether a change was made on the specified path. /// /// Note that <paramref name="type"/> can be used as a bitmask including /// multiple types, in which case any detected match will yield a "true" result. /// </summary> /// <param name="type"></param> /// <param name="path"></param> /// <returns></returns> public bool Contains(FileEventType type, string path) { // Early-out to avoid iterating if we don't have anything of that type if (!this.Any(type)) { return(false); } if (path == null) { return(false); } foreach (FileEvent item in this.fileEvents) { if ((item.Type & type) == FileEventType.None) { continue; } if (item.Path == path || item.OldPath == path) { return(true); } } return(false); }
public FileEvent(FileEventType eventType, FileEntry entry, string newName = null, int oldCount = FileEntry.NotCounted) { EventType = eventType; FileEntry = entry; NewName = newName; OldCount = oldCount; }
public FileEvents(FileEventType Type, string Name, uint Length = 0, uint Offset = uint.MaxValue) { this.Type = Type; this.Name = Name; this.Length = Length; this.Offset = Offset; }
public void Report(LineCountProgress value) { FileEvent fileEvent = value.FileEvent; if (value.Status == LineCountStatus.Success) { FileEventType t = fileEvent.EventType; if (t == FileEventType.Initialize) { fileEvent.FileEntry.LineCount = value.Count; } if (t == FileEventType.Update) { fileEvent.OldCount = fileEvent.FileEntry.LineCount; } if (t == FileEventType.Create || t == FileEventType.Update) { fileEvent.FileEntry.LineCount = value.Count; OnFolderChanged(this, fileEvent); } // deletes don't come back through progress and are logged all at once elsewhere } else if (value.Status == LineCountStatus.TimedOut) { // When and if the file is released, it will be logged as an update. } }
/// <summary> /// Запустить мониторинг файловой системы /// </summary> public void StartFileWatcher(string path, FileEventType type) { _monService.StartFileWatcher(new FileWatcherSettingsDto() { Path = path, EventType = type }); }
internal void OnFileChanged(object sender, FileEventRaisedArgs e) { FileEventType fileEvent = e.EventType; string oldFilePath = e.OldFilePath; string newFilePath = e.FilePath; //bool hasSrcML = e.HasSrcML; switch (fileEvent) { case FileEventType.FileAdded: return; case FileEventType.FileChanged: ChangeMethodsInChangedFile(oldFilePath); break; case FileEventType.FileDeleted: DeleteMethodsInDeletedFile(oldFilePath); break; case FileEventType.FileRenamed: ChangeMethodsInRenamedFile(oldFilePath, newFilePath); break; } }
public FileEvent(FileEventType type, string oldPath, string path, bool isDirectory) { this.Type = type; this.Path = path; this.OldPath = oldPath; this.IsDirectory = isDirectory; }
/// <summary> /// Constructor. /// </summary> /// <param name="eventType"></param> /// <param name="pathToFile"></param> /// <param name="oldPathToFile"></param> /// <param name="hasSrcML"></param> public FileEventRaisedArgs(FileEventType eventType, string pathToFile, string oldPathToFile, bool hasSrcML) { this.EventType = eventType; this.FilePath = pathToFile; this.OldFilePath = oldPathToFile; this.HasSrcML = hasSrcML; }
/// <summary> /// Returns whether a change was made on the specified <see cref="Resource"/>. /// </summary> /// <param name="type"></param> /// <param name="content"></param> /// <returns></returns> /// <seealso cref="FileSystemChangedEventArgs.Contains(FileEventType, string)"/> public bool Contains(FileEventType type, Resource content) { if (content == null) { return(false); } return(this.Contains(type, content.Path)); }
List <FileEvent> AsFileEventsInternal(FileEventType fileEventType) { var list = new List <FileEvent>(Files.Count); foreach (FileEntry f in Files.Values) { var fileEvent = new FileEvent(fileEventType, f); list.Add(fileEvent); } return(list); }
/// <summary> /// Оповестить об событии в файловой системе /// </summary> private void NotifyFileWatcher(FileEventType type, string message) { Run(_subscriber, s => s.NotifyFileWatcherEvent( new NotifyFileWatcherEventDto() { Entry = new FileWatcherLogEntryDto() { EventType = type, Message = message } })); }
public void Add(FileEventType Type, string Filter) { FileWatchInfo watch = new FileWatchInfo(); watch.Type = Type; watch.Filter = Filter; watch.Enabled = true; WatchInfo.Add(watch); RefreshUI(); }
public FileSystemChangedEventArgs(IEnumerable <FileEvent> fileEvents) { this.fileEvents = new List <FileEvent>(fileEvents); foreach (FileEvent item in this.fileEvents) { if (item.IsDirectory) { this.directoryEventTypes |= item.Type; } else { this.fileEventTypes |= item.Type; } } }
/// <summary> /// Returns whether a change was made on any of the specified <see cref="Resource"/> instances. /// </summary> /// <param name="type"></param> /// <param name="content"></param> /// <returns></returns> /// <seealso cref="FileSystemChangedEventArgs.Contains(FileEventType, IEnumerable{string})"/> public bool Contains(FileEventType type, IEnumerable <ContentRef <Resource> > content) { // Early-out to avoid iterating if we don't have anything of that type if (!this.Any(type)) { return(false); } foreach (ContentRef <Resource> item in content) { if (this.Contains(type, item)) { return(true); } } return(false); }
/// <summary> /// Returns whether a change was made on any of the specified paths. /// /// Note that <paramref name="type"/> can be used as a bitmask including /// multiple types, in which case any detected match will yield a "true" result. /// </summary> /// <param name="type"></param> /// <param name="paths"></param> /// <returns></returns> public bool Contains(FileEventType type, IEnumerable <string> paths) { // Early-out to avoid iterating if we don't have anything of that type if (!this.Any(type)) { return(false); } foreach (string path in paths) { if (this.Contains(type, path)) { return(true); } } return(false); }
public List <FileEvent> AsFileEvents(FileEventType fileEventType) { if (_enforceLocks) { try { Monitor.Enter(_lockObject); return(AsFileEventsInternal(fileEventType)); } finally { Monitor.Exit(_lockObject); } } else { return(AsFileEventsInternal(fileEventType)); } }
/// <summary> /// Returns whether a change was made on a <see cref="Resource"/> of the specified type. /// </summary> /// <param name="type"></param> /// <param name="content"></param> /// <returns></returns> /// <seealso cref="FileSystemChangedEventArgs.Contains(FileEventType, string)"/> public bool Contains(FileEventType type, Type contentType) { // Early-out to avoid iterating if we don't have anything of that type if (!this.Any(type)) { return(false); } if (contentType == null) { return(false); } foreach (FileEvent item in this.FileEvents) { if ((item.Type & type) == FileEventType.None) { continue; } if (item.IsDirectory) { continue; } ContentRef <Resource> content = new ContentRef <Resource>(item.Path); if (contentType.IsAssignableFrom(content.ResType)) { return(true); } if (item.Type == FileEventType.Renamed) { ContentRef <Resource> oldContent = new ContentRef <Resource>(item.OldPath); if (contentType.IsAssignableFrom(oldContent.ResType)) { return(true); } } } return(false); }
/// <summary> /// Handle file creation/deletion cases. The way these parameters work is: rgFirstIndices /// contains a list of the starting index into the changeProjectItems array for each project /// listed in the changedProjects list /// Example: if you get two projects, then rgFirstIndices should have two elements, the /// first element is probably zero since rgFirstIndices would start at zero. /// Then item two in the rgFirstIndices array is where in the changeProjectItems list that /// the second project's changed items reside. /// TODO: may process files in parallel /// </summary> /// <param name="cProjects"></param> /// <param name="cFiles"></param> /// <param name="rgpProjects"></param> /// <param name="rgFirstIndices"></param> /// <param name="rgpszMkDocuments"></param> /// <param name="type"></param> /// <returns></returns> private int OnNotifyFileAddRemove(int cProjects, int cFiles, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgpszMkDocuments, FileEventType type) { int projItemIndex = 0; for (int changeProjIndex = 0; changeProjIndex < cProjects; changeProjIndex++) { int endProjectIndex = ((changeProjIndex + 1) == cProjects) ? rgpszMkDocuments.Length : rgFirstIndices[changeProjIndex + 1]; for (; projItemIndex < endProjectIndex; projItemIndex++) { if (rgpProjects[changeProjIndex] != null) { RespondToVSFileChangedEvent(rgpszMkDocuments[projItemIndex], null, type); } } } return(VSConstants.S_OK); }
/// <summary> /// Respond to events of file creation/change/deletion in the solution in Visual Studio /// </summary> /// <param name="filePath"></param> /// <param name="oldFilePath"></param> /// <param name="type"></param> public void RespondToVSFileChangedEvent(string filePath, string oldFilePath, FileEventType type) { //SrcMLFileLogger.DefaultLogger.Info("SolutionMonitor.RespondToVSFileChangedEvent(): filePath = " + filePath + ", oldFilePath = " + oldFilePath + ", type = " + type); switch (type) { case FileEventType.FileAdded: AddFile(filePath); break; case FileEventType.FileChanged: AddFile(filePath); break; case FileEventType.FileDeleted: DeleteFile(filePath); break; case FileEventType.FileRenamed: // actually not used DeleteFile(oldFilePath); AddFile(filePath); break; } }
public void CheckSrcMLFiles() { string sourcePath = fera.FilePath; string oldSourcePath = fera.OldFilePath; FileEventType type = fera.EventType; bool hasSrcML = fera.HasSrcML; if (type == FileEventType.FileAdded || type == FileEventType.FileChanged) { Assert.IsTrue((receivedFileAdded || receivedFileUpdated)); if (hasSrcML) { SrcMLArchive archive = srcMLService.GetSrcMLArchive(); Assert.IsNotNull(archive, "GetSrcMLArchive returned null."); string srcMLPath = archive.GetXmlPathForSourcePath(sourcePath); ////WriteLog(logFilePath, "Adding/Updating srcMLPath = " + srcMLPath); Assert.IsTrue(File.Exists(srcMLPath), "The srcML file [" + srcMLPath + "] does not exist."); Assert.AreEqual(new FileInfo(sourcePath).LastWriteTime, new FileInfo(srcMLPath).LastWriteTime); XElement xelement = srcMLService.GetXElementForSourceFile(sourcePath); Assert.IsNotNull(xelement, "GetXElementForSourceFile returned null."); } } else if (type == FileEventType.FileDeleted) { Assert.IsTrue(receivedFileDeleted); SrcMLArchive archive = srcMLService.GetSrcMLArchive(); Assert.IsNotNull(archive, "GetSrcMLArchive returned null."); string srcMLPath = archive.GetXmlPathForSourcePath(sourcePath); ////WriteLog(logFilePath, "Deleting srcMLPath = " + srcMLPath); Assert.IsFalse(File.Exists(srcMLPath), "The srcML file [" + srcMLPath + "] still exists."); XElement xelementX = srcMLService.GetXElementForSourceFile(sourcePath); Assert.IsNull(xelementX, "GetXElementForSourceFile returned not null."); } receivedFileAdded = receivedFileUpdated = receivedFileDeleted = false; fera = null; }
/// <summary> /// Handle project addition/deletion cases. The way these parameters work is: /// pHierarchy: Pointer to the IVsHierarchy interface of the project being loaded or closed. /// fAddedRemoved: For addition, true if the project is added to the solution after the /// solution is opened, false if the project is added to the solution while /// the solution is being opened. For deletion, true if the project was /// removed from the solution before the solution was closed, false if the /// project was removed from the solution while the solution was being /// closed. /// type: FileEventType.FileAdded - project addition, FileEventType.FileDeleted - project /// deletion. /// TODO: may process files in parallel /// </summary> /// <param name="pHierarchy"></param> /// <param name="fAddedRemoved"></param> /// <param name="type"></param> public void NotifyProjectAddRemove(IVsHierarchy pHierarchy, int fAddedRemoved, FileEventType type) { List <string> fileList = new List <string>(); string projectName; pHierarchy.GetCanonicalName(VSConstants.VSITEMID_ROOT, out projectName); //SrcMLFileLogger.DefaultLogger.Info("Project Name: [" + projectName + "]"); // Find out this project in the solution tree var allProjects = OpenSolution.getProjects(); var enumerator = allProjects.GetEnumerator(); while (enumerator.MoveNext()) { Project project = enumerator.Current as Project; string fullName = null; try { //SrcMLFileLogger.DefaultLogger.Info("FileName: [" + project.FileName + "]"); fullName = project.FileName; } catch (Exception e) { // Ignore unloaded project. It would cause a Not Implemented Exception for an // unloaded project. //SrcMLFileLogger.DefaultLogger.Error(SrcMLExceptionFormatter.CreateMessage(e, "Exception in SolutionMonitor.NotifyProjectAddRemove() - ")); continue; } if (fullName != null && (fullName.Equals(projectName) || fullName.ToLower().Contains(projectName.ToLower()))) { SrcMLFileLogger.DefaultLogger.Info("Project: [" + projectName + "]"); ProcessProject(project, null, fileList); break; } } // Generate or delete srcML files for the source files in this project try { foreach (var filePath in fileList) { if (FileEventType.FileAdded.Equals(type)) { //SrcMLFileLogger.DefaultLogger.Info(">>> AddFile(" + filePath + ")"); AddFile(filePath); } else if (FileEventType.FileDeleted.Equals(type)) { //SrcMLFileLogger.DefaultLogger.Info(">>> DeleteFile(" + filePath + ")"); DeleteFile(filePath); } } } catch (Exception e) { SrcMLFileLogger.DefaultLogger.Error(SrcMLExceptionFormatter.CreateMessage(e, "Exception when batch adding or deleting srcML files for a specified project.")); } }
/// <summary> /// Returns whether a change was made on the specified <see cref="Resource"/>. /// </summary> /// <param name="type"></param> /// <param name="content"></param> /// <returns></returns> /// <seealso cref="FileSystemChangedEventArgs.Contains(FileEventType, string)"/> public bool Contains(FileEventType type, ContentRef <Resource> content) { return(this.Contains(type, content.Path)); }
/// <summary> /// /// </summary> public void ProcessEvent(string sourceFullPath, FileEventType eventType) { DateTime processStartTime; List<WatchFolder> watchFolders; Log.Instance.Debug("ProcessEvent: There was a " + eventType.ToString().ToUpper() + " event in " + sourceFullPath); if (string.IsNullOrEmpty(sourceFullPath)) return; processStartTime = DateTime.UtcNow; watchFolders = m_watchFolders; // Full Path may or may not be a folder of interst to watch. (Need to loop through all -- folder may appear more than once) foreach (WatchFolder f in watchFolders) { Log.Instance.Debug("ProcessEvent: Is this event under at the level " + f.FullPathToWatch.QuoteWrap() + " (or below if subfolders=true) ?"); if (ProcessThisFolder(sourceFullPath, f) && ProcessThisFilename(sourceFullPath, f)) { Log.Instance.Debug("ProcessEvent: Yes."); Log.Instance.Debug("ProcessEvent: Filename matches filter. Folder is within scope."); // Does the action match a watch action for this folder? Log.Instance.Debug("ProcessEvent: Is the event type the expected " + f.WatchFolderAction.EventType.ToString().ToUpper() + "?"); if (f.WatchFolderAction.EventType == eventType) { Log.Instance.Debug("ProcessEvent: Yes.(Event Type = " + eventType.ToString() + ")"); // Determine destination filename string destinationFileName = BuildDestinationName(sourceFullPath, f.WatchFolderAction.OutputFilePattern, false); destinationFileName = string.Concat(destinationFileName, FilePath.GetExtension(sourceFullPath)); // Determine destination foldername string destinationFolderName = FilePath.GetAbsolutePath(BuildDestinationName(sourceFullPath, f.WatchFolderAction.OutputFolderPattern, true)); // Determine destination sourceFullPath string destinationPathName = FilePath.GetUniqueFilePath(Path.Combine(destinationFolderName, destinationFileName)); Log.Instance.Debug("ProcessEvent: Destination FullPath = " + destinationPathName.QuoteWrap()); if (string.IsNullOrEmpty(destinationFileName)) { Log.Instance.Error("ProcessEvent: Destination filename is missing or empty. Processing continuting to next watch folder"); break; } switch (f.WatchFolderAction.Action) { case FileAction.Copy: Log.Instance.Debug("ProcessEvent: Try COPY File " + FilePath.GetFileName(sourceFullPath).QuoteWrap() + " to " + destinationPathName.QuoteWrap()); try { if (!Directory.Exists(destinationFolderName)) Directory.CreateDirectory(destinationFolderName); FilePath.WaitForReadLockExclusive(sourceFullPath); File.Copy(sourceFullPath, destinationPathName, true); TimeSpan duration = processStartTime.Subtract(DateTime.UtcNow).Negate(); Log.Instance.Info("ProcessEvent: File COPY successsful to " + destinationPathName.QuoteWrap() + " Duration = " + duration.ToElapsedTimeString()); if (f.ProduceResultsFile) { XmlDocument resultsXml = BuildResultsXml(sourceFullPath, destinationPathName, processStartTime, duration); Log.Instance.Debug("ProcessEvent: Successfully produced stats XML document."); writeXml(resultsXml, destinationPathName); } } catch (Exception ex) { Log.Instance.ErrorException("ProcessEvent: Cannot COPY file to " + destinationPathName.QuoteWrap(), ex); } break; case FileAction.Move: Log.Instance.Debug("ProcessEvent: Try MOVE File " + Path.GetFileName(sourceFullPath).QuoteWrap() + " to " + destinationPathName.QuoteWrap()); try { if (!Directory.Exists(destinationFolderName)) Directory.CreateDirectory(destinationFolderName); FilePath.WaitForReadLockExclusive(sourceFullPath); File.Move(sourceFullPath, destinationPathName); TimeSpan duration = processStartTime.Subtract(DateTime.UtcNow).Negate(); Log.Instance.Info("ProcessEvent: File MOVE successsful to " + destinationPathName.QuoteWrap() + " Duration = " + duration.ToElapsedTimeString()); if (f.ProduceResultsFile) { XmlDocument resultsXml = BuildResultsXml(sourceFullPath, destinationPathName, processStartTime, duration); Log.Instance.Debug("ProcessEvent: Successfully produced stats XML document."); writeXml(resultsXml, destinationPathName); } } catch (Exception ex) { Log.Instance.ErrorException("ProcessEvent: Cannot MOVE file to " + destinationPathName.QuoteWrap(), ex); } break; default: Log.Instance.Info("ProcessEvent: Default Action - Logging an event on file: " + sourceFullPath.QuoteWrap()); break; } } else { Log.Instance.Debug("ProcessEvent: No."); } } else { Log.Instance.Debug("ProcessEvent: No."); } } }
public FileFinishedChangingEventArgs(string filePath, FileEventType changeType, object userState) { FilePath = filePath; ChangeType = changeType; UserState = userState; }
public FileChangingItem(string filePath, FileEventType fileEventType) : base(filePath, fileEventType) { }
/// <summary> /// Returns whether any directory changes of the specified type were made. /// /// Note that <paramref name="type"/> can be used as a bitmask including /// multiple types, in which case any detected match will yield a "true" result. /// </summary> /// <param name="type"></param> /// <returns></returns> public bool AnyDirectories(FileEventType type) { return((this.directoryEventTypes & type) != FileEventType.None); }
private void button1_Click_2(object sender, EventArgs e) { FileEventType Event = (FileEventType)cbAction.SelectedIndex; fileWatchMan.Add(Event, tbFilter.Text); }
/// <summary> /// Constructor. /// </summary> /// <param name="eventType"></param> /// <param name="pathToFile"></param> /// <param name="hasSrcML"></param> public FileEventRaisedArgs(FileEventType eventType, string pathToFile, bool hasSrcML) : this(eventType, pathToFile, pathToFile, hasSrcML) { }
/// <summary> /// Constructor. /// </summary> /// <param name="eventType"></param> /// <param name="pathToFile"></param> /// <param name="oldPathToFile"></param> public FileEventRaisedArgs(FileEventType eventType, string pathToFile, string oldPathToFile) : this(eventType, pathToFile, oldPathToFile, false) { }
public void GenerateXmlForDirectoryTest() { ManualResetEvent resetEvent = new ManualResetEvent(false); var archive = new SrcMLArchive(ArchiveDirectory, false, new SrcMLGenerator(Path.Combine(SrcMLHelper.GetSrcMLRootDirectory(), SrcMLHelper.srcMLExecutableLocation))); FileEventType expectedEventType = FileEventType.FileAdded; FileEventType actualEventType = FileEventType.FileChanged; archive.FileChanged += (sender, e) => { actualEventType = e.EventType; bool shouldHaveSrcML = (e.EventType != FileEventType.FileDeleted); Assert.AreEqual(shouldHaveSrcML, e.HasSrcML); resetEvent.Set(); }; Dictionary <string, string> sourceFiles = new Dictionary <string, string>() { { Path.Combine(SourceDirectory, "foo.c"), String.Format(@"int foo() {{{0}printf(""hello world!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "bar.c"), String.Format(@"int bar() {{{0} printf(""goodbye, world!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir1", "foo1.c"), String.Format(@"int foo1() {{{0}printf(""hello world 1!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir1", "bar1.c"), String.Format(@"int bar1() {{{0} printf(""goodbye, world 1!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir2", "foo2.c"), String.Format(@"int foo2() {{{0}printf(""hello world 2!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir2", "bar2.c"), String.Format(@"int bar2() {{{0} printf(""goodbye, world 2!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir1", "subdir11", "foo11.c"), String.Format(@"int foo11() {{{0}printf(""hello world 11!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir1", "subdir11", "bar11.c"), String.Format(@"int bar11() {{{0} printf(""goodbye, world 11!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir1", "subdir12", "foo12.c"), String.Format(@"int foo12() {{{0}printf(""hello world 12!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir1", "subdir12", "bar12.c"), String.Format(@"int bar12() {{{0} printf(""goodbye, world 12!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir2", "subdir21", "foo21.c"), String.Format(@"int foo21() {{{0}printf(""hello world 21!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir2", "subdir21", "bar21.c"), String.Format(@"int bar21() {{{0} printf(""goodbye, world 21!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir2", "subdir22", "foo22.c"), String.Format(@"int foo22() {{{0}printf(""hello world 22!"");{0}}}", Environment.NewLine) }, { Path.Combine(SourceDirectory, "subdir2", "subdir22", "bar22.c"), String.Format(@"int bar22() {{{0} printf(""goodbye, world 22!"");{0}}}", Environment.NewLine) }, }; foreach (var fileDataPair in sourceFiles) { var directory = Path.GetDirectoryName(fileDataPair.Key); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } File.WriteAllText(fileDataPair.Key, fileDataPair.Value); archive.AddOrUpdateFile(fileDataPair.Key); Assert.That(resetEvent.WaitOne(300)); Assert.AreEqual(expectedEventType, actualEventType); } foreach (var fileName in sourceFiles.Keys) { Assert.That(archive.ContainsFile(fileName), String.Format("Archive should contain {0}", fileName)); } var changedFileName = Path.Combine(SourceDirectory, "foo.c"); var changedFileContents = String.Format(@"int foo() {{{0}printf(""hello world! changed"");{0}}}", Environment.NewLine); expectedEventType = FileEventType.FileChanged; File.WriteAllText(changedFileName, changedFileContents); File.SetLastWriteTime(changedFileName, DateTime.Now); Assert.That(archive.ContainsFile(changedFileName)); Assert.That(archive.IsOutdated(changedFileName)); archive.AddOrUpdateFile(changedFileName); Assert.That(resetEvent.WaitOne(300)); Assert.AreEqual(expectedEventType, actualEventType); expectedEventType = FileEventType.FileDeleted; var deletedFileName = Path.Combine(SourceDirectory, "subdir1", "subdir12", "bar12.c"); File.Delete(deletedFileName); Assert.That(archive.IsOutdated(deletedFileName)); archive.DeleteFile(deletedFileName); Assert.That(resetEvent.WaitOne(300)); Assert.AreEqual(expectedEventType, actualEventType); expectedEventType = FileEventType.FileRenamed; var movedFileName = Path.Combine(SourceDirectory, "subdir1", "subdir11", "foo11.c"); var newNameForMoved = Path.Combine(SourceDirectory, "subdir1", "subdir11", "foo1111111.c"); File.Move(movedFileName, newNameForMoved); Assert.That(archive.IsOutdated(movedFileName)); archive.RenameFile(movedFileName, newNameForMoved); Assert.That(resetEvent.WaitOne(300)); Assert.AreEqual(expectedEventType, actualEventType); Assert.That(archive.ContainsFile(newNameForMoved)); Assert.IsFalse(archive.ContainsFile(movedFileName)); }
public void TestCppFileOperations() { // setup Project project = TestHelpers.GetProjects(TestSolution).FirstOrDefault(); Assert.IsNotNull(project, "Couldn't get the project"); var archive = TestHelpers.TestScaffold.Service.GetSrcMLArchive(); var service = TestHelpers.TestScaffold.Service; int scanInterval = 5; int scanIntervalMs = scanInterval * 1000; service.ScanInterval = scanInterval; Assert.IsNotNull(archive, "Could not get the SrcML Archive"); AutoResetEvent resetEvent = new AutoResetEvent(false); string expectedFilePath = null; FileEventType expectedEventType = FileEventType.FileDeleted; EventHandler <FileEventRaisedArgs> action = (o, e) => { lock (TestLock) { if (e.FilePath.Equals(expectedFilePath, StringComparison.InvariantCultureIgnoreCase) && e.EventType == expectedEventType) { resetEvent.Set(); } } }; TestHelpers.TestScaffold.Service.SourceFileChanged += action; // add a file var fileTemplate = Path.Combine(TestConstants.TemplatesFolder, "NewCPPClass1.cpp"); expectedFilePath = Path.Combine(Path.GetDirectoryName(project.FullName), "NewCPPClass1.cpp"); expectedEventType = FileEventType.FileAdded; File.Copy(fileTemplate, expectedFilePath); var item = project.ProjectItems.AddFromFile(expectedFilePath); Console.WriteLine(item.FileNames[0]); Console.WriteLine(expectedFilePath); project.Save(); Assert.IsTrue(resetEvent.WaitOne(scanIntervalMs)); Assert.IsTrue(archive.ContainsFile(expectedFilePath)); Assert.IsFalse(archive.IsOutdated(expectedFilePath)); //// rename a file //string oldFilePath = expectedFilePath; //expectedFilePath = Path.Combine(Path.GetDirectoryName(project.FullName), "NewCPPClass2.cpp"); //expectedEventType = FileEventType.FileAdded; //item = TestSolution.FindProjectItem(oldFilePath); //item.SaveAs(expectedFilePath); //File.Delete(oldFilePath); //project.Save(); //Assert.IsTrue(resetEvent.WaitOne(500)); //Assert.IsTrue(archive.ContainsFile(expectedFilePath), "The archive should contain {0}", expectedFilePath); //Assert.IsFalse(archive.ContainsFile(oldFilePath), "the archive should not contain {0}", oldFilePath); //Assert.IsFalse(archive.IsOutdated(expectedFilePath), String.Format("{0} is outdated", expectedFilePath)); // delete the file expectedEventType = FileEventType.FileDeleted; item = TestSolution.FindProjectItem(expectedFilePath); item.Delete(); project.Save(); Assert.IsTrue(resetEvent.WaitOne(scanIntervalMs)); Assert.IsFalse(archive.IsOutdated(expectedFilePath)); //Assert.AreEqual(2, archive.FileUnits.Count()); TestHelpers.TestScaffold.Service.SourceFileChanged -= action; }
/// <summary> /// Handle project addition/deletion cases. The way these parameters work is: /// pHierarchy: Pointer to the IVsHierarchy interface of the project being loaded or closed. /// fAddedRemoved: For addition, true if the project is added to the solution after the /// solution is opened, false if the project is added to the solution while /// the solution is being opened. For deletion, true if the project was /// removed from the solution before the solution was closed, false if the /// project was removed from the solution while the solution was being /// closed. /// type: FileEventType.FileAdded - project addition, FileEventType.FileDeleted - project /// deletion. /// TODO: may process files in parallel /// </summary> /// <param name="pHierarchy"></param> /// <param name="fAddedRemoved"></param> /// <param name="type"></param> public void NotifyProjectAddRemove(IVsHierarchy pHierarchy, int fAddedRemoved, FileEventType type) { List<string> fileList = new List<string>(); string projectName; pHierarchy.GetCanonicalName(VSConstants.VSITEMID_ROOT, out projectName); //SrcMLFileLogger.DefaultLogger.Info("Project Name: [" + projectName + "]"); // Find out this project in the solution tree var allProjects = OpenSolution.getProjects(); var enumerator = allProjects.GetEnumerator(); while(enumerator.MoveNext()) { Project project = enumerator.Current as Project; string fullName = null; try { //SrcMLFileLogger.DefaultLogger.Info("FileName: [" + project.FileName + "]"); fullName = project.FileName; } catch(Exception e) { // Ignore unloaded project. It would cause a Not Implemented Exception for an // unloaded project. //SrcMLFileLogger.DefaultLogger.Error(SrcMLExceptionFormatter.CreateMessage(e, "Exception in SolutionMonitor.NotifyProjectAddRemove() - ")); continue; } if(fullName != null && (fullName.Equals(projectName) || fullName.ToLower().Contains(projectName.ToLower()))) { SrcMLFileLogger.DefaultLogger.Info("Project: [" + projectName + "]"); ProcessProject(project, null, fileList); break; } } // Generate or delete srcML files for the source files in this project try { foreach(var filePath in fileList) { if(FileEventType.FileAdded.Equals(type)) { //SrcMLFileLogger.DefaultLogger.Info(">>> AddFile(" + filePath + ")"); AddFile(filePath); } else if(FileEventType.FileDeleted.Equals(type)) { //SrcMLFileLogger.DefaultLogger.Info(">>> DeleteFile(" + filePath + ")"); DeleteFile(filePath); } } } catch(Exception e) { SrcMLFileLogger.DefaultLogger.Error(SrcMLExceptionFormatter.CreateMessage(e, "Exception when batch adding or deleting srcML files for a specified project.")); } }
/// <summary> /// Handle file creation/deletion cases. The way these parameters work is: rgFirstIndices /// contains a list of the starting index into the changeProjectItems array for each project /// listed in the changedProjects list /// Example: if you get two projects, then rgFirstIndices should have two elements, the /// first element is probably zero since rgFirstIndices would start at zero. /// Then item two in the rgFirstIndices array is where in the changeProjectItems list that /// the second project's changed items reside. /// TODO: may process files in parallel /// </summary> /// <param name="cProjects"></param> /// <param name="cFiles"></param> /// <param name="rgpProjects"></param> /// <param name="rgFirstIndices"></param> /// <param name="rgpszMkDocuments"></param> /// <param name="type"></param> /// <returns></returns> private int OnNotifyFileAddRemove(int cProjects, int cFiles, IVsProject[] rgpProjects, int[] rgFirstIndices, string[] rgpszMkDocuments, FileEventType type) { int projItemIndex = 0; for(int changeProjIndex = 0; changeProjIndex < cProjects; changeProjIndex++) { int endProjectIndex = ((changeProjIndex + 1) == cProjects) ? rgpszMkDocuments.Length : rgFirstIndices[changeProjIndex + 1]; for(; projItemIndex < endProjectIndex; projItemIndex++) { if(rgpProjects[changeProjIndex] != null) { RespondToVSFileChangedEvent(rgpszMkDocuments[projItemIndex], null, type); } } } return VSConstants.S_OK; }
public FileEventItem(string filePath, FileEventType fileEventType) { FilePath = filePath; FileEventType = fileEventType; }
public WatchAction() { Enabled = false; EventType = FileEventType.None; OutputPatternStatus = FilePatternStatus.NoneSet; Action = FileAction.Notify; OutputFolderPattern = new DestinationFilePattern[1]; OutputFilePattern = new DestinationFilePattern[1]; }
/// <summary> /// Returns whether any file changes of the specified type were made. /// /// Note that <paramref name="type"/> can be used as a bitmask including /// multiple types, in which case any detected match will yield a "true" result. /// </summary> /// <param name="type"></param> /// <returns></returns> public bool AnyFiles(FileEventType type) { return((this.fileEventTypes & type) != FileEventType.None); }
/// <summary> /// Respond to events of file creation/change/deletion in the solution in Visual Studio /// </summary> /// <param name="filePath"></param> /// <param name="oldFilePath"></param> /// <param name="type"></param> public void RespondToVSFileChangedEvent(string filePath, string oldFilePath, FileEventType type) { //SrcMLFileLogger.DefaultLogger.Info("SolutionMonitor.RespondToVSFileChangedEvent(): filePath = " + filePath + ", oldFilePath = " + oldFilePath + ", type = " + type); switch(type) { case FileEventType.FileAdded: AddFile(filePath); break; case FileEventType.FileChanged: AddFile(filePath); break; case FileEventType.FileDeleted: DeleteFile(filePath); break; case FileEventType.FileRenamed: // actually not used DeleteFile(oldFilePath); AddFile(filePath); break; } }
/// <summary> /// Class constructor /// </summary> public FileBaseEvent(FileEventType typeOfEvent) { TypeOfEvent = typeOfEvent; }
/// <summary> /// Add a file event that has occurred for a file. /// </summary> /// <param name="filePath"></param> /// <param name="fileEventType"></param> private void Push(string filePath, FileEventType fileEventType) { if (string.IsNullOrEmpty(filePath)) return; IFileChangingItem item = new FileChangingItem(filePath, fileEventType); item.FireTime = DateTime.Now.AddMilliseconds(PollTime); _filesChanging.Add(filePath, item); if (string.IsNullOrEmpty(_nextFileToCheck)) { GetNextFileToCheck(); } }