question

MiPakTeh-6272 avatar image
0 Votes"
MiPakTeh-6272 asked TimonYang-MSFT commented

Put all files from Filesystemwacther to virtual Mode ListView

Hi All,

What I try to do is;

How to put all files coming using filesystemwacther into Virtual Mode ListView.Yhis code have one Class and
code Form.Somebody can show.

Class;

 using System;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Security.Permissions;
 using static System.IO.Path;
    
 namespace Learning_13
 {
     public class FileOperations : FileSystemWatcher
     {
         /// <summary>
         /// Path to check for new files
         /// </summary>
         public string MonitorPath { get; set; }
         /// <summary>
         /// Path to move file(s) too
         /// </summary>
         public string TargetPath { get; set; }
    
         public FileOperations(string monitorPath, string targetPath, string extension)
         {
             MonitorPath = monitorPath;
             TargetPath = targetPath;
    
             Created += OnCreated;
             Error += OnError;
    
             Path = MonitorPath;
             Filter = extension;
    
             EnableRaisingEvents = true;
    
             NotifyFilter = NotifyFilters.Attributes
                            | NotifyFilters.CreationTime
                            | NotifyFilters.DirectoryName
                            | NotifyFilters.FileName
                            | NotifyFilters.LastAccess
                            | NotifyFilters.LastWrite
                            | NotifyFilters.Security
                            | NotifyFilters.Size;
         }
    
         private void OnCreated(object sender, FileSystemEventArgs e)
         {
    
             try
             {
    
    
                 System.IO.StreamWriter fileV = new System.IO.StreamWriter(MonitorPath);
                 foreach (var sfile in MonitorPath)
                 {
                     fileV.WriteLine(sfile);
                 }
    
                 var targetFile = Combine(TargetPath, GetFileName(e.FullPath));
                 if (File.Exists(targetFile))
                 {
                     File.Delete(targetFile);
                 }
    
                 File.Move(e.FullPath, targetFile);
             }
             catch (Exception exception)
             {
                 Debug.WriteLine(exception.Message);
             }
         }
    
         public void Start()
         {
             EnableRaisingEvents = true;
         }
    
         public void Stop()
         {
             EnableRaisingEvents = false;
         }
    
         private static void OnError(object sender, ErrorEventArgs e) => DisplayException(e.GetException());
         /// <summary>
         /// For debug purposes
         /// For a production environment write to a log file
         /// </summary>
         /// <param name="ex"></param>
         private static void DisplayException(Exception ex)
         {
             if (ex != null)
             {
                 Debug.WriteLine($"Message: {ex.Message}");
                 Debug.WriteLine("Stacktrace:");
                 Debug.WriteLine(ex.StackTrace);
                 Debug.WriteLine("");
    
                 DisplayException(ex.InnerException);
             }
         }
     }
 }

  1. Form Code

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows.Forms;

    namespace Learning_13
    {
    public partial class Form1 : Form
    {

          List<string> filesAdded = new List<string>();
        
             private readonly FileOperations _fileOperations =
                  new FileOperations(@"C:\", @"D:\Keeper\", "*.txt");
             public Form1()
             {
                 InitializeComponent();
                 Closing += OnClosing;
             }
        
             private void OnClosing(object sender, CancelEventArgs e)
             {
                 _fileOperations.Stop();
             }
        
             void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
             {
                 var item = new ListViewItem();
                 if (_fileOperations.MonitorPath.Count() > 0)
                 {
                     item.Text = _fileOperations.MonitorPath[e.ItemIndex].ToString();
                 }
                 e.Item = item;
        
             }
        
             private void Start_Click(object sender, EventArgs e)
             {
                 _fileOperations.Start();
                 listView1.VirtualListSize = _fileOperations.MonitorPath.Count();
        
             }
        
             private void Stop_Click(object sender, EventArgs e)
             {
                 _fileOperations.Stop();
             }
        
             private void Form1_Load(object sender, EventArgs e)
             {
                 System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
                 listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
                 listView1.VirtualMode = true;
                 listView1.View = View.Details;
                 listView1.GridLines = true;
                 listView1.Columns.Add("Filename", 600);
        
                 listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
        
             }
         }
     }
    


...Thank.



dotnet-csharp
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

This comment is not a solution to your problem, but a big warning about something horribly wrong in your code. NEVER do this:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
It is a huge mistake. It will cause your program to crash intermittently and inconsistently at random times.
If the program is complaining about detecting illegal cross thread calls, then spend the time to fix these calls. Disabling the check for them is looking for trouble. It will make your program unreliable and it will ether crash or corrupt the display at random times.

0 Votes 0 ·

Hi APoblacion,

Thank for your comment.

base on coding , It possible call the Class "_fileOperations" to produce the result "MonitorPath" in ListView Virtual mode.
can show me how?


Thank

0 Votes 0 ·

@MiPakTeh-6272
There are many places in the code that I don't understand.
1. The listView1_RetrieveVirtualItem method.
This method simply looks at the length of the MonitorPath and adds each character in the path as a ListViewItem to the listview.

83069-2.png
2. The OnCreated method of the FileOperations class.

 System.IO.StreamWriter fileV = new System.IO.StreamWriter(MonitorPath);

There is an exception in this code. StreamWriter needs a file path, and MonitorPath is a folder path, and it is best to put it in a using statement, or close it after writing, otherwise you will trigger an IOException and write failure.

83096-4.png
Could you please describe your needs in detail in words?
The current code does not seem to express your meaning very clearly.

0 Votes 0 ·
2.png (870 B)
4.png (1.9 KiB)
Show more comments

1 Answer

TimonYang-MSFT avatar image
0 Votes"
TimonYang-MSFT answered TimonYang-MSFT commented

I did not completely use your code but re-written a piece of code myself. There are two main differences between this code and your code.

I didn't customize FileOperations to inherit FileSystemWatcher but directly used FileSystemWatche because I don't really understand the role of some methods in FileOperations.

When the Created event is used, the file is moved to the target path as soon as it is created, and we have no time to rename it. This causes all files to use the default name, and the code will delete the file with the name already existing, so there will always be only one file with the default name in the target path.

 public partial class Form1 : Form
 {
     private string TargetPath = @"d:\test11\";
     private bool IsNewFile = false;
     private List<ListViewItem> myCache = new List<ListViewItem>();
     public Form1()
     {
         InitializeComponent();
     }

     private void Form1_Load(object sender, EventArgs e)
     {
         listView1.View = View.Details;
         listView1.GridLines = true;
         listView1.VirtualMode = true;
         listView1.RetrieveVirtualItem += ListView1_RetrieveVirtualItem;
         listView1.Columns.Add("Filename", 600);
         var watcher = new FileSystemWatcher(@"d:\test");

         watcher.NotifyFilter = NotifyFilters.Attributes
                              | NotifyFilters.CreationTime
                              | NotifyFilters.DirectoryName
                              | NotifyFilters.FileName
                              | NotifyFilters.LastAccess
                              | NotifyFilters.LastWrite
                              | NotifyFilters.Security
                              | NotifyFilters.Size;
         watcher.Created += OnCreated;
         watcher.Renamed += OnRenamed;
         watcher.Filter = "*.txt";
         watcher.IncludeSubdirectories = true;
         watcher.EnableRaisingEvents = true;
     }

     private void ListView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
     {
         if (myCache .Count>0)
         {
             e.Item = myCache[e.ItemIndex];
         }
     }

     private void OnCreated(object sender, FileSystemEventArgs e)
     {
         IsNewFile = true;
     }
    private void OnRenamed(object sender, RenamedEventArgs e)
     {
         if (IsNewFile)
         {
             string TargetFile = Path.Combine(TargetPath, e.Name);

             using (StreamWriter fileV = new System.IO.StreamWriter(e.FullPath))
             {
                 foreach (var sfile in e.FullPath)
                 {
                     fileV.WriteLine(sfile);
                 }
             }
             if (File.Exists(TargetFile))
             {
                 File.Delete(TargetFile);
             }
            
             //The File.Delete process may not end in time, causing File.Move to be abnormal, indicating that the file is being used.                 
             Thread.S*leep(100);
             File.Move(e.FullPath, TargetFile);
             myCache.Add(new ListViewItem() { Text = TargetFile });
             this.Invoke((MethodInvoker)delegate ()
             {
                 listView1.VirtualListSize = myCache.Count;
             });
         }
     }

Update:

I build a new winform application, and then add a listview from the toolbox.

I made a small modification to the code, because when the monitored folder is the root directory of c, in fact, new files created in its subdirectories will also be monitored.

The previous code will have an error in handling this situation. I modified it slightly in the OnRenamed handler:

                 FileInfo fileInfo = new FileInfo(e.FullPath);
                 string TargetFile = Path.Combine(TargetPath, fileInfo.Name);

The current situation is as follows:

87294-1.gif

The file mentioned in the exception message is obviously not the *.txt file that we need to monitor. It is a file of Sql Server and contains transaction logs for Microsoft SQL Server relational database that record all completed and pending transactions since last checkpoint.

I am not sure why it was detected, but when I re-checked the program, I found a problem that I hadn't noticed before.

If we create a file but do not rename it, and then rename the previous file, the previous file will be written and moved.

I added a new field and used it like this:

         private string newFilePath;
         private void OnCreated(object sender, FileSystemEventArgs e)
         {
             newFilePath = e.FullPath;
             IsNewFile = true;
         }
         private void OnRenamed(object sender, RenamedEventArgs e)
         {
             if (IsNewFile && e.OldFullPath == newFilePath)
            // ......

If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


1.gif (182.0 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@MiPakTeh-6272
I added some steps of my operation and found a problem that I didn't notice before. Please check the new content in the answer.

0 Votes 0 ·