This is a Windows-specific bug caused by System.IO.Path.GetFullPath calling System.IO.PathHelper.TryExpandShortFileName for paths containing a ~.
Symptoms
IFileSystemWatcher events created from a SubFileSystem will be silently discarded if all these conditions are met:
We're on Windows
The path given when creating the SubFileSystem has incorrect case
The path segments with incorrect case are short enough to be a SFN
The changed file name includes a ~ anywhere
We noticed this when watching for .cs file changes while editing using Visual Studio. VS won't directly write to files when saving, instead creating a temporary file named something like Example~xxxx.tmp, which is then renamed to replace the actual target file.
Cause
GetFullPath gets called by all the PhysicalFileSystem.Watcher.Remap methods via ConvertPathFromInternalImpl:
Summary
This is a Windows-specific bug caused by System.IO.Path.GetFullPath calling System.IO.PathHelper.TryExpandShortFileName for paths containing a
~
.Symptoms
IFileSystemWatcher events created from a SubFileSystem will be silently discarded if all these conditions are met:
~
anywhereWe noticed this when watching for .cs file changes while editing using Visual Studio. VS won't directly write to files when saving, instead creating a temporary file named something like
Example~xxxx.tmp
, which is then renamed to replace the actual target file.Cause
GetFullPath gets called by all the PhysicalFileSystem.Watcher.Remap methods via ConvertPathFromInternalImpl:
https://github.com/xoofx/zio/blob/a4b9faf133e018bb738c1c195b56aa9712b41e90/src/Zio/FileSystems/PhysicalFileSystem.cs#L980
This can change the case of the path - even if it was already rooted - if it contains a
~
.Then, SubFileSystem.Watcher.TryConvertPath checks if paths are contained in its SubPath by calling UPath.IsInDirectory, which is case-sensitive:
https://github.com/xoofx/zio/blob/a4b9faf133e018bb738c1c195b56aa9712b41e90/src/Zio/UPathExtensions.cs#L202
When this fails, the event gets silently discarded.
Reproduction
Here's a test demonstrating this:
https://github.com/Facepunch/zio/blob/073a0201895ab9af996c1b30790fbe3c2ccaa5d0/src/Zio.Tests/FileSystems/TestSubFileSystem.cs#L77-L112
Only one case fails: the one where all the conditions above are met.
Related
59