我正在使用
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();
}
}
}
我的建议是尝试将
this.watcher.Renamed
添加到处理的事件中,然后在应用 Renamed
表达式时注意 not过滤掉
this.watcher.NotifyFilter
事件。这至少可以弥补 Excel 执行从菜单调用的 Save
操作的方式。根据下面所示的测试方法,Changed
事件永远不会被触发。当我制作一个模拟 MachineWatcher
并连接 all 包括 Renamed
在内的事件时,第一个事件发生在打开文件时创建名为 ~$ExcelTestFile.xlsx 的临时文件时。然后,每次发生 Save
操作时,都会发生以下序列:
Created
临时文件事件(例如,在此过程中,它被任意命名为 ECA83C30)。Changed
事件(大概是因为主文件的修改版本被复制到其中)。Renamed
D03DF176.tmp 事件(大概来自 ECA83C30)Renamed
real 目标的事件,名为 ExcelTestFile.xlxs 的文件(可能是来自 D03DF176.tmp 的复制操作)Delete
D03DF176.tmp但是没有
Change
目标Excel文件的事件即使它最终得到一个新的LastWriteTime
。这让我很震惊,但看看你是否可以重现!
模拟最小的
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();
}