-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add Microsoft.IO.Redist for directory enumeration. #6771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
eb07877
eb73956
81311bd
e397615
c80abab
55addd2
1a37ff2
fc9d8b1
5e1ae3f
d6b2109
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using Microsoft.Build.Utilities; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
|
@@ -16,6 +17,20 @@ internal class ManagedFileSystem : IFileSystem | |
|
||
public static ManagedFileSystem Singleton() => ManagedFileSystem.Instance; | ||
|
||
private static bool ShouldUseMicrosoftIO | ||
{ | ||
get | ||
{ | ||
#if !MICROSOFT_BUILD_ENGINE_OM_UNITTESTS | ||
return ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_0); | ||
#else | ||
// We need to mock usage of ChangeWaves class, | ||
// because Microsoft.Build.Engine.OM.UnitTests should not have access to internals of Microsoft.Build.Framework. | ||
return true; | ||
#endif | ||
} | ||
} | ||
|
||
protected ManagedFileSystem() { } | ||
|
||
public TextReader ReadFile(string path) | ||
|
@@ -38,19 +53,78 @@ public byte[] ReadFileAllBytes(string path) | |
return File.ReadAllBytes(path); | ||
} | ||
|
||
#if FEATURE_MSIOREDIST | ||
private static IEnumerable<string> HandleFileLoadException( | ||
Func<string, string, Microsoft.IO.SearchOption, IEnumerable<string>> enumerateFunctionDelegate, | ||
string path, | ||
string searchPattern, | ||
Microsoft.IO.SearchOption searchOption | ||
) | ||
{ | ||
try | ||
{ | ||
return enumerateFunctionDelegate(path, searchPattern, searchOption); | ||
} | ||
// Microsoft.IO.Redist has a dependency on System.Buffers and if System.Buffers assembly is not found the line above throws an exception. | ||
// However, FileMatcher class (that in most cases calls the enumeration) does not allow to fail on a IO-related exception. Such behavior hides the actual exception and makes it obscure. | ||
// We rethrow it to make it fail with a proper error message and call stack. | ||
catch (FileLoadException ex) | ||
{ | ||
throw new InvalidOperationException(ex.Message, ex); | ||
} | ||
// Sometimes FileNotFoundException is thrown when there is an assembly load failure. In this case it should have FusionLog. | ||
catch (FileNotFoundException ex) when (ex.FusionLog != null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't the I don't see There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It works when fusion logging is disabled. The FusionLog in this case consists of a warning "WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1." If But I suppose you are right and we can remove this |
||
{ | ||
throw new InvalidOperationException(ex.Message, ex); | ||
} | ||
} | ||
#endif | ||
|
||
public virtual IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption) | ||
{ | ||
#if FEATURE_MSIOREDIST | ||
return ShouldUseMicrosoftIO | ||
? HandleFileLoadException( | ||
(path, searchPattern, searchOption) => Microsoft.IO.Directory.EnumerateFiles(path, searchPattern, searchOption), | ||
path, | ||
searchPattern, | ||
(Microsoft.IO.SearchOption)searchOption | ||
) | ||
: Directory.EnumerateFiles(path, searchPattern, searchOption); | ||
#else | ||
return Directory.EnumerateFiles(path, searchPattern, searchOption); | ||
#endif | ||
} | ||
|
||
public virtual IEnumerable<string> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption) | ||
{ | ||
#if FEATURE_MSIOREDIST | ||
return ShouldUseMicrosoftIO | ||
? HandleFileLoadException( | ||
(path, searchPattern, searchOption) => Microsoft.IO.Directory.EnumerateDirectories(path, searchPattern, searchOption), | ||
path, | ||
searchPattern, | ||
(Microsoft.IO.SearchOption)searchOption | ||
) | ||
: Directory.EnumerateDirectories(path, searchPattern, searchOption); | ||
#else | ||
return Directory.EnumerateDirectories(path, searchPattern, searchOption); | ||
#endif | ||
} | ||
|
||
public virtual IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption) | ||
{ | ||
#if FEATURE_MSIOREDIST | ||
return ShouldUseMicrosoftIO | ||
? HandleFileLoadException( | ||
(path, searchPattern, searchOption) => Microsoft.IO.Directory.EnumerateFileSystemEntries(path, searchPattern, searchOption), | ||
path, | ||
searchPattern, (Microsoft.IO.SearchOption)searchOption | ||
) | ||
: Directory.EnumerateFileSystemEntries(path, searchPattern, searchOption); | ||
#else | ||
return Directory.EnumerateFileSystemEntries(path, searchPattern, searchOption); | ||
#endif | ||
} | ||
|
||
public FileAttributes GetAttributes(string path) | ||
|
Uh oh!
There was an error while loading. Please reload this page.