FileSystemWatcher 仅在第一次更改后引发

问题描述 投票:0回答:1

我正在使用

FileSystemWatcher

一切正常。当我保存文件时,会正确引发 Changed 事件。 但如果我第二次保存文件,则不再引发 Changed 事件。

我是否需要添加额外的代码,以便每次保存文件时都会引发?

这是我的代码的一部分,如果这有任何帮助的话:

我做了一个课程

MachineWatcher
,因为在我的项目中,我需要创建不同观察者类型的列表(但我认为这不会改变问题):

public class MachineWatcher
{
    private Machine machine { get; set; }
    public Machine Machine { get { return this.machine; } set { this.machine = value; } }
    private string typeWatcher { get; set; } = "";
    public string TypeWatcher { get { return this.typeWatcher; } set { this.typeWatcher = value; } }
    FileSystemWatcher watcher { get; set; }
    public FileSystemWatcher Watcher { get { return this.watcher; } set { this.watcher = value; } }
    public MachineWatcher()
    {

    }
    public MachineWatcher(string type,string directoryStock,string fileFilter)
    {
        this.typeWatcher = type;
        this.watcher = new FileSystemWatcher();
        this.watcher.Path = Path.GetDirectoryName(directoryStock);
        this.watcher.Filter = fileFilter;
        this.watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
        this.watcher.Changed += new FileSystemEventHandler(OnFeedBackNesterCreated);
        this.watcher.Created += new FileSystemEventHandler(OnFeedBackNesterCreated);
        
        this.watcher.EnableRaisingEvents = true;
    }
    private void OnFeedBackNesterCreated(object source, FileSystemEventArgs e)
    {
        string filePath = e.FullPath;
        LaunchingOrder newLo = this.readXmlFile(filePath);
        if(newLo!=null)
        {
            newLo.Fichier = filePath;
            newLo.AddOrUpdate();
        }
    }
        
}
c# filesystemwatcher file-watcher
1个回答
2
投票

我的建议是尝试将

this.watcher.Renamed
添加到处理的事件中,然后在应用 Renamed 表达式时注意
not
过滤掉
this.watcher.NotifyFilter
事件。这至少可以弥补 Excel 执行从菜单调用的
Save
操作的方式。根据下面所示的测试方法,
Changed
事件永远不会被触发。当我制作一个模拟
MachineWatcher
并连接 all 包括
Renamed
在内的事件时,第一个事件发生在打开文件时创建名为 ~$ExcelTestFile.xlsx 的临时文件时。然后,每次发生
Save
操作时,都会发生以下序列:

  1. Created
    临时文件事件(例如,在此过程中,它被任意命名为 ECA83C30)。
  2. 此 tmp 文件会触发两个
    Changed
    事件(大概是因为主文件的修改版本被复制到其中)。
  3. Renamed
    D03DF176.tmp 事件(大概来自 ECA83C30
  4. Renamed
    real 目标的事件,名为 ExcelTestFile.xlxs 的文件(可能是来自 D03DF176.tmp 的复制操作)
  5. Delete
    D03DF176.tmp
  6. 的活动

但是没有

Change
目标Excel文件的事件即使它最终得到一个新的
LastWriteTime
。这让我很震惊,但看看你是否可以重现!

test log


模拟最小的

MachineWatcher

public class MachineWatcher
{
    public MachineWatcher(string type, string directoryStock, string fileFilter)
    {
        watcher = new FileSystemWatcher(directoryStock, fileFilter);
        watcher.Created += onModified;
        watcher.Changed += onModified;
        watcher.Renamed += onModified;
        watcher.Deleted += onModified; 
        // watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
        watcher.EnableRaisingEvents = true;
    }
    FileSystemWatcher watcher { get; }

    private void onModified(object sender, FileSystemEventArgs e)
    {
        switch (e.ChangeType)
        {
            case WatcherChangeTypes.Created:
                OnFeedBackNesterCreated(sender, e);
                Console.WriteLine($" LastWriteTime: {new FileInfo(e.FullPath).LastWriteTime}");
                break;
            case WatcherChangeTypes.Deleted:
                Console.WriteLine($"Deleted: {e.Name}");
                break;
            case WatcherChangeTypes.Changed:
                var ext = Path.GetExtension(e.FullPath);
                switch (ext)
                {
                    case ".xlsx":
                        Console.Write($"Changed: {e.Name}");
                        break;
                    case ".txt":
                        try
                        {
                            Console.Write($"Changed: {e.Name} {File.ReadAllLines(e.FullPath).Last()}");
                        }
                        catch
                        {
                            Console.Write($"Changed: {e.Name} (in transition)");
                        }
                        break;
                    case "":
                        Console.Write($"Changed: {e.Name} (no extension)");
                        break;
                    default:
                        Console.Write($"The '{ext}' extension is not supported");
                        break;
                }
                Console.WriteLine($" LastWriteTime: {new FileInfo(e.FullPath).LastWriteTime}");
                break;
            case WatcherChangeTypes.Renamed:
                Console.Write($"Renamed: {e.Name}");
                Console.WriteLine($" LastWriteTime: {new FileInfo(e.FullPath).LastWriteTime}");
                break;
            default:
                break;
        }
    }

    private void OnFeedBackNesterCreated(object source, FileSystemEventArgs e)
    {
        Console.Write($"Created: {e.Name}");
    }
}

使用控制台练习

MachineWatcher

static void Main(string[] args)
{
    const int SPACING = 500;
    string appData = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        "custom_file_system_watcher");

    // Ensure that the root directory exists
    Directory.CreateDirectory(appData);

    // Make an instance of MachineWatcher
    var mw = new MachineWatcher(
        null, // In minimal reproducible sample this is unused
        appData, 
        "*.*");

    // Force Delete (if exists)
    var testFile = Path.Combine(appData, "testFile.txt");
    File.Delete(testFile);
    Thread.Sleep(SPACING);

    // Force Create + Change
    File.WriteAllText(
            testFile, 
            $"{DateTime.Now}{Environment.NewLine}");
    Thread.Sleep(SPACING);

    // Force N Changes
    var N = 5;
    for (int i = 1; i <= N; i++)
    {
        // Using Append because File.WriteAllText is two events not one.
        File.AppendAllText(testFile, $"Change #{i}{Environment.NewLine}");
        Thread.Sleep(SPACING);
    }

    // Force Rename
    var testFileRenamed = Path.Combine(appData, "testFile.Renamed.txt");
    File.Copy(testFile, testFileRenamed, overwrite: true);
    Thread.Sleep(SPACING);

    // Prove that if the Excel file LastWriteTime changes, we'll see it
    var excelFile = Path.Combine(appData, "ExcelTestFile.xlsx");
    var fileInfo = new FileInfo(excelFile);
    if(fileInfo.Exists)
    {
        Console.WriteLine();
        Console.WriteLine("Proves that if the Excel file LastWriteTime changes, we'll see it:");
        try
        {
            fileInfo.LastWriteTime = DateTime.Now;
        }
        catch
        {
            Console.WriteLine("CANNOT CHANGE TIMESTAMP: EXCEL FILE IS ALREADY OPEN");
        }
    }
    Thread.Sleep(SPACING);

    Console.WriteLine();
    Console.WriteLine("Waiting for Excel file changes...");
    Console.ReadKey();
}
© www.soinside.com 2019 - 2024. All rights reserved.