Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<Import Project="..\Directory.Build.props" />
<PropertyGroup>
<IsAspNetCoreApp>true</IsAspNetCoreApp>
<UnsupportedOSPlatforms>browser</UnsupportedOSPlatforms>
<IncludePlatformAttributes>true</IncludePlatformAttributes>
</PropertyGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<RootNamespace>Microsoft.Extensions.FileProviders</RootNamespace>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppCurrent)-Browser;netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>$(NetCoreAppCurrent);netstandard2.0;net461</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableDefaultItems>true</EnableDefaultItems>
<PackageDescription>File provider for physical files for Microsoft.Extensions.FileProviders.</PackageDescription>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetsBrowser)' == 'true'">
<EnableDefaultItems>false</EnableDefaultItems>
<GeneratePlatformNotSupportedAssemblyMessage>SR.FileProvidersPhysical_PlatformNotSupported</GeneratePlatformNotSupportedAssemblyMessage>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(CommonPath)Extensions\EmptyDisposable.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,13 @@ internal PhysicalFilesWatcher CreateFileWatcher()
string root = PathUtils.EnsureTrailingSlash(Path.GetFullPath(Root));
Comment thread
buyaa-n marked this conversation as resolved.

// When both UsePollingFileWatcher & UseActivePolling are set, we won't use a FileSystemWatcher.
FileSystemWatcher watcher = UsePollingFileWatcher && UseActivePolling ? null : new FileSystemWatcher(root);
FileSystemWatcher watcher = UsePollingFileWatcher && UseActivePolling ? null :
#if NETCOREAPP
OperatingSystem.IsBrowser() ? throw new PlatformNotSupportedException(SR.Format(SR.FileSystemWatcher_PlatformNotSupported, typeof(FileSystemWatcher))) : new FileSystemWatcher(root);
#else
Comment on lines +164 to +167

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this still throw PNSE when creating a PhysicalFileProvider on browser? Shouldn't the logic be something like:

(UsePollingFileWatcher && UseActivePolling) || OperatingSystem.IsBrowser() ? null : ...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, so we should always fallback to use polling on browser. That makes sense to me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: PR #56257 addresses this in 276b008.

new FileSystemWatcher(root);
#endif

return new PhysicalFilesWatcher(root, watcher, UsePollingFileWatcher, _filters)
{
UseActivePolling = UseActivePolling,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Runtime.Versioning;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -88,6 +89,13 @@ public PhysicalFilesWatcher(

if (fileSystemWatcher != null)
{
#if NETCOREAPP
if (OperatingSystem.IsBrowser())
{
throw new PlatformNotSupportedException(SR.Format(SR.FileSystemWatcher_PlatformNotSupported, typeof(FileSystemWatcher)));
Comment thread
jozkee marked this conversation as resolved.
}
#endif

_fileWatcher = fileSystemWatcher;
_fileWatcher.IncludeSubdirectories = true;
_fileWatcher.Created += OnChanged;
Expand Down Expand Up @@ -140,7 +148,10 @@ public IChangeToken CreateFileChangeToken(string filter)
}

IChangeToken changeToken = GetOrAddChangeToken(filter);
// We made sure that browser never uses FileSystemWatcher.
#pragma warning disable CA1416 // Validate platform compatibility
TryEnableFileSystemWatcher();
#pragma warning restore CA1416 // Validate platform compatibility

return changeToken;
}
Expand Down Expand Up @@ -264,6 +275,7 @@ protected virtual void Dispose(bool disposing)
}
}

[UnsupportedOSPlatform("browser")]
private void OnRenamed(object sender, RenamedEventArgs e)
{
// For a file name change or a directory's name change notify registered tokens.
Expand Down Expand Up @@ -296,11 +308,13 @@ ex is DirectoryNotFoundException ||
}
}

[UnsupportedOSPlatform("browser")]
private void OnChanged(object sender, FileSystemEventArgs e)
{
OnFileSystemEntryChange(e.FullPath);
}

[UnsupportedOSPlatform("browser")]
private void OnError(object sender, ErrorEventArgs e)
{
// Notify all cache entries on error.
Expand All @@ -310,6 +324,7 @@ private void OnError(object sender, ErrorEventArgs e)
}
}

[UnsupportedOSPlatform("browser")]
private void OnFileSystemEntryChange(string fullPath)
{
try
Expand All @@ -332,6 +347,7 @@ ex is SecurityException ||
}
}

[UnsupportedOSPlatform("browser")]
private void ReportChangeForMatchedEntries(string path)
{
if (string.IsNullOrEmpty(path))
Expand Down Expand Up @@ -368,6 +384,7 @@ private void ReportChangeForMatchedEntries(string path)
}
}

[UnsupportedOSPlatform("browser")]
private void TryDisableFileSystemWatcher()
{
if (_fileWatcher != null)
Expand All @@ -385,6 +402,7 @@ private void TryDisableFileSystemWatcher()
}
}

[UnsupportedOSPlatform("browser")]
private void TryEnableFileSystemWatcher()
{
if (_fileWatcher != null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema

Microsoft ResX Schema
Version 2.0

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
Expand All @@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>

There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
Expand Down Expand Up @@ -129,7 +129,7 @@
<data name="UnexpectedFileSystemInfo" xml:space="preserve">
<value>Unexpected type of FileSystemInfo</value>
</data>
<data name="FileProvidersPhysical_PlatformNotSupported" xml:space="preserve">
<value>Microsoft.Extensions.FileProviders.Physical is not supported on this platform.</value>
<data name="FileSystemWatcher_PlatformNotSupported" xml:space="preserve">
<value>The type {0} is not supported on this platform, use polling instead.</value>
</data>
</root>
2 changes: 0 additions & 2 deletions src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,7 @@ private void CreateHostingEnvironment()
_hostingEnvironment.ApplicationName = Assembly.GetEntryAssembly()?.GetName().Name;
}

#pragma warning disable CA1416 // 'PhysicalFileProvider' is unsupported on: 'browser' https://github.com/dotnet/runtime/issues/56178
_hostingEnvironment.ContentRootFileProvider = _defaultProvider = new PhysicalFileProvider(_hostingEnvironment.ContentRootPath);
#pragma warning restore CA1416 // 'PhysicalFileProvider' is unsupported on: 'browser'
}

private string ResolveContentRootPath(string contentRootPath, string basePath)
Expand Down