diff --git a/eng/Analyzers.props b/eng/Analyzers.props
index 4405ca11687fe..bd9dc5ddb53e8 100644
--- a/eng/Analyzers.props
+++ b/eng/Analyzers.props
@@ -3,11 +3,13 @@
$(MSBuildThisFileDirectory)CodeAnalysis.ruleset
false
+ true
+
diff --git a/eng/CodeAnalysis.ruleset b/eng/CodeAnalysis.ruleset
index e3626e28f62a9..fe63588a31cd4 100644
--- a/eng/CodeAnalysis.ruleset
+++ b/eng/CodeAnalysis.ruleset
@@ -254,8 +254,6 @@
-
-
diff --git a/eng/CodeAnalysis.test.ruleset b/eng/CodeAnalysis.test.ruleset
index f1f75fb00a2fa..142a1e8e86384 100644
--- a/eng/CodeAnalysis.test.ruleset
+++ b/eng/CodeAnalysis.test.ruleset
@@ -255,6 +255,7 @@
+
diff --git a/eng/Versions.props b/eng/Versions.props
index a716f2d29f655..303f6e82d8351 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -162,6 +162,7 @@
5.0.0-preview-20201009.2
6.0.100-preview.5.21267.3
+ $(MicrosoftNETILLinkTasksVersion)
6.0.0-preview.5.21267.1
diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs
index 7ca797e7d0a8e..10786ab1afe24 100644
--- a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs
+++ b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.cs
@@ -62,10 +62,12 @@ public partial class DependencyContext
public DependencyContext(Microsoft.Extensions.DependencyModel.TargetInfo target, Microsoft.Extensions.DependencyModel.CompilationOptions compilationOptions, System.Collections.Generic.IEnumerable compileLibraries, System.Collections.Generic.IEnumerable runtimeLibraries, System.Collections.Generic.IEnumerable runtimeGraph) { }
public Microsoft.Extensions.DependencyModel.CompilationOptions CompilationOptions { get { throw null; } }
public System.Collections.Generic.IReadOnlyList CompileLibraries { get { throw null; } }
+ [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static Microsoft.Extensions.DependencyModel.DependencyContext Default { get { throw null; } }
public System.Collections.Generic.IReadOnlyList RuntimeGraph { get { throw null; } }
public System.Collections.Generic.IReadOnlyList RuntimeLibraries { get { throw null; } }
public Microsoft.Extensions.DependencyModel.TargetInfo Target { get { throw null; } }
+ [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static Microsoft.Extensions.DependencyModel.DependencyContext Load(System.Reflection.Assembly assembly) { throw null; }
public Microsoft.Extensions.DependencyModel.DependencyContext Merge(Microsoft.Extensions.DependencyModel.DependencyContext other) { throw null; }
}
@@ -95,6 +97,7 @@ public partial class DependencyContextLoader
{
public DependencyContextLoader() { }
public static Microsoft.Extensions.DependencyModel.DependencyContextLoader Default { get { throw null; } }
+ [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public Microsoft.Extensions.DependencyModel.DependencyContext Load(System.Reflection.Assembly assembly) { throw null; }
}
public partial class DependencyContextWriter
diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj
index 86069259a9bc9..2901720d3fe1f 100644
--- a/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj
+++ b/src/libraries/Microsoft.Extensions.DependencyModel/ref/Microsoft.Extensions.DependencyModel.csproj
@@ -4,5 +4,6 @@
+
diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContext.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContext.cs
index cb9f01fbd70f4..6e58abf313409 100644
--- a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContext.cs
+++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContext.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
@@ -10,6 +11,9 @@ namespace Microsoft.Extensions.DependencyModel
{
public class DependencyContext
{
+
+ [UnconditionalSuppressMessage("SingleFile", "IL3002:Avoid calling members marked with 'RequiresAssemblyFilesAttribute' when publishing as a single-file",
+ Justification = "The annotation should be on the static constructor but is Compiler Generated, annotating the caller Default method instead")]
private static readonly Lazy _defaultContext = new Lazy(LoadDefault);
public DependencyContext(TargetInfo target,
@@ -46,6 +50,7 @@ public DependencyContext(TargetInfo target,
RuntimeGraph = runtimeGraph.ToArray();
}
+ [RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static DependencyContext Default => _defaultContext.Value;
public TargetInfo Target { get; }
@@ -74,6 +79,7 @@ public DependencyContext Merge(DependencyContext other)
);
}
+ [RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
private static DependencyContext LoadDefault()
{
var entryAssembly = Assembly.GetEntryAssembly();
@@ -85,6 +91,7 @@ private static DependencyContext LoadDefault()
return Load(entryAssembly);
}
+ [RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static DependencyContext Load(Assembly assembly)
{
return DependencyContextLoader.Default.Load(assembly);
diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs
index a411055df2c5c..2bd5d410d466b 100644
--- a/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs
+++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/DependencyContextLoader.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
@@ -50,6 +51,7 @@ private static Stream GetResourceStream(Assembly assembly, string name)
return assembly.GetManifestResourceStream(name);
}
+ [RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public DependencyContext Load(Assembly assembly)
{
if (assembly == null)
@@ -103,6 +105,7 @@ private DependencyContext LoadContext(IDependencyContextReader reader, string lo
return null;
}
+ [RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
private DependencyContext LoadAssemblyContext(Assembly assembly, IDependencyContextReader reader)
{
using (Stream stream = GetResourceStream(assembly, assembly.GetName().Name + DepsJsonExtension))
@@ -125,6 +128,7 @@ private DependencyContext LoadAssemblyContext(Assembly assembly, IDependencyCont
return null;
}
+ [RequiresAssemblyFiles(Message = "The use of DependencyContextLoader is not supported when publishing as single-file")]
private string GetDepsJsonPath(Assembly assembly)
{
// Assemblies loaded in memory (e.g. single file) return empty string from Location.
diff --git a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj
index 7d21c765085a3..81b60b7135205 100644
--- a/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj
+++ b/src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj
@@ -11,6 +11,8 @@ Microsoft.Extensions.DependencyModel.DependencyContext
+
+
@@ -29,4 +31,5 @@ Microsoft.Extensions.DependencyModel.DependencyContext
+
diff --git a/src/libraries/Microsoft.NETCore.Platforms/src/AssemblyResolver.cs b/src/libraries/Microsoft.NETCore.Platforms/src/AssemblyResolver.cs
index a0f4aaad29bc0..9427028aa5fe3 100644
--- a/src/libraries/Microsoft.NETCore.Platforms/src/AssemblyResolver.cs
+++ b/src/libraries/Microsoft.NETCore.Platforms/src/AssemblyResolver.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
@@ -27,6 +28,8 @@ public static void Enable()
// has run.
}
+ [UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "The code has a fallback to use AppDomain.CurrentDomain.BaseDirectory so it will work correctly in single-file")]
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// apply any existing policy
diff --git a/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj b/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj
index 8dbe46d4b5c3e..8e13e283ca9f1 100644
--- a/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj
+++ b/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj
@@ -1,4 +1,4 @@
-
+
$(NetCoreAppToolCurrent);net472
@@ -21,6 +21,7 @@
+
@@ -38,7 +39,7 @@
-
+
@@ -55,4 +56,4 @@
-
\ No newline at end of file
+
diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/src/Microsoft.XmlSerializer.Generator.csproj b/src/libraries/Microsoft.XmlSerializer.Generator/src/Microsoft.XmlSerializer.Generator.csproj
index a560c12aaf67c..6c22b92bfba5e 100644
--- a/src/libraries/Microsoft.XmlSerializer.Generator/src/Microsoft.XmlSerializer.Generator.csproj
+++ b/src/libraries/Microsoft.XmlSerializer.Generator/src/Microsoft.XmlSerializer.Generator.csproj
@@ -6,9 +6,13 @@
FxResources.$(AssemblyName.Replace('-', '_')).SR
Exe
netstandard2.0
+ false
+
+
-
\ No newline at end of file
+
+
diff --git a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj
index 6284508e40e9a..d60b2055cb977 100644
--- a/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj
+++ b/src/libraries/System.ComponentModel.Composition/src/System.ComponentModel.Composition.csproj
@@ -182,6 +182,9 @@
+
+
+
@@ -211,4 +214,4 @@
-
\ No newline at end of file
+
diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs
index 338661efe93db..d35b5df575d1f 100644
--- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs
+++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs
@@ -543,6 +543,8 @@ private void ThrowIfDisposed()
private string GetDisplayName() =>
$"{GetType().Name} (Assembly=\"{Assembly.FullName}\")"; // NOLOC
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "Setting a CodeBase is single file compatible")]
private static Assembly LoadAssembly(string codeBase)
{
Requires.NotNullOrEmpty(codeBase, nameof(codeBase));
diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs
index 64a4498443efd..758af025e35b4 100644
--- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs
+++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesigntimeLicenseContext.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Collections;
@@ -57,6 +58,8 @@ private string GetLocalPath(string fileName)
return uri.LocalPath + uri.Fragment;
}
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "Suppressing the warning until gets fixed, see https://github.com/dotnet/runtime/issues/50821")]
public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly)
{
if (_savedLicenseKeys == null || _savedLicenseKeys[type.AssemblyQualifiedName] == null)
diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj
index ef35470847194..a7fcc9e7abaeb 100644
--- a/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj
+++ b/src/libraries/System.Configuration.ConfigurationManager/src/System.Configuration.ConfigurationManager.csproj
@@ -251,6 +251,7 @@
+
diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs
index 0f41dd3a3732b..a92612ca0b0f4 100644
--- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs
+++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Reflection;
@@ -28,6 +29,8 @@ internal sealed class ClientConfigPaths
private readonly bool _includesUserConfig;
private string _companyName;
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "Code handles single file case")]
private ClientConfigPaths(string exePath, bool includeUserConfig)
{
_includesUserConfig = includeUserConfig;
diff --git a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj
index 23b766558c448..33436282ae22e 100644
--- a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj
+++ b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj
@@ -128,7 +128,9 @@
-
+
+
+
@@ -138,4 +140,4 @@
Condition="'$(TargetsWindows)' == 'true'"
DependsOnTargets="ResolveProjectReferences"
BeforeTargets="GetFilesToPackage" />
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLog.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLog.cs
index e96de7a6f9867..8115e3d5c2678 100644
--- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLog.cs
+++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/EventLog.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
@@ -691,6 +692,8 @@ internal static RegistryKey GetEventLogRegKey(string machine, bool writable)
return null;
}
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "The code handles if the path is null by calling AppContext.BaseDirectory")]
internal static string GetDllPath(string machineName)
{
string dllPath = Path.Combine(NetFrameworkUtils.GetLatestBuildDllDirectory(machineName), DllName);
diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs
index 91758fc6c0242..5483a382ac674 100644
--- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs
+++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/Helper.Win32Unix.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Security;
using System.Threading;
@@ -27,6 +28,8 @@ internal static string GetDataDirectory(IsolatedStorageScope scope)
return dataDirectory;
}
+ [UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "Code handles single-file deployment by using the information of the .exe file")]
internal static void GetDefaultIdentityAndHash(out object identity, out string hash, char separator)
{
// In .NET Framework IsolatedStorage uses identity from System.Security.Policy.Evidence to build
@@ -53,9 +56,6 @@ internal static void GetDefaultIdentityAndHash(out object identity, out string h
throw new IsolatedStorageException(SR.IsolatedStorage_Init);
AssemblyName assemblyName = assembly.GetName();
-#pragma warning disable SYSLIB0012
- Uri codeBase = new Uri(assembly.CodeBase!);
-#pragma warning restore SYSLIB0012
hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName)!;
if (hash != null)
@@ -65,8 +65,15 @@ internal static void GetDefaultIdentityAndHash(out object identity, out string h
}
else
{
- hash = "Url" + separator + IdentityHelper.GetNormalizedUriHash(codeBase);
- identity = codeBase;
+ string? location = assembly.Location;
+ // In case of SingleFile deployment, Assembly.Location is empty.
+ if (location == string.Empty)
+ location = Environment.ProcessPath;
+ if (string.IsNullOrEmpty(location))
+ throw new IsolatedStorageException(SR.IsolatedStorage_Init);
+ Uri locationUri = new Uri(location);
+ hash = "Url" + separator + IdentityHelper.GetNormalizedUriHash(locationUri);
+ identity = locationUri;
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs
index e497fdf6d395b..c8b5fcba415f5 100644
--- a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
@@ -8,6 +9,8 @@ namespace System
{
public static partial class AppContext
{
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "Single File apps should always set APP_CONTEXT_BASE_DIRECTORY therefore code handles Assembly.Location equals null")]
private static string GetBaseDirectoryCore()
{
// Fallback path for hosts that do not set APP_CONTEXT_BASE_DIRECTORY explicitly
diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttribute.cs
index 2b7bbcb6b9952..358bf3136da83 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttribute.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/RequiresAssemblyFilesAttribute.cs
@@ -12,7 +12,12 @@ namespace System.Diagnostics.CodeAnalysis
AttributeTargets.Property,
Inherited = false,
AllowMultiple = false)]
- public sealed class RequiresAssemblyFilesAttribute : Attribute
+#if SYSTEM_PRIVATE_CORELIB
+ public
+#else
+ internal
+#endif
+ sealed class RequiresAssemblyFilesAttribute : Attribute
{
///
/// Initializes a new instance of the class.
@@ -32,4 +37,4 @@ public RequiresAssemblyFilesAttribute() { }
///
public string? Url { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs
index ccc60df7818bc..6baab555151b4 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs
@@ -81,6 +81,7 @@ public virtual IEnumerable ExportedTypes
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type[] GetForwardedTypes() { throw NotImplemented.ByDesign; }
+ [RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual string? CodeBase => throw NotImplemented.ByDesign;
public virtual MethodInfo? EntryPoint => throw NotImplemented.ByDesign;
public virtual string? FullName => throw NotImplemented.ByDesign;
@@ -115,6 +116,7 @@ public virtual IEnumerable ExportedTypes
public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
+ [RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual string EscapedCodeBase => AssemblyName.EscapeCodeBase(CodeBase);
[RequiresUnreferencedCode("Assembly.CreateInstance is not supported with trimming. Use Type.GetType instead.")]
@@ -152,6 +154,7 @@ public virtual IEnumerable ExportedTypes
public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version? version) { throw NotImplemented.ByDesign; }
public virtual FileStream? GetFile(string name) { throw NotImplemented.ByDesign; }
+ [RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual FileStream[] GetFiles() => GetFiles(getResourceModules: false);
public virtual FileStream[] GetFiles(bool getResourceModules) { throw NotImplemented.ByDesign; }
@@ -268,6 +271,8 @@ public static Assembly LoadFile(string path)
}
[RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
+ [UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "The assembly is loaded by specifying a path outside of the single-file bundle, the location of the path will not be empty if the path exist, otherwise it will be handled as null")]
private static Assembly? LoadFromResolveHandler(object? sender, ResolveEventArgs args)
{
Assembly? requestingAssembly = args.RequestingAssembly;
diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs
index 6b0ca27a948b5..0853bfff0685a 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Configuration.Assemblies;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.Text;
using CultureInfo = System.Globalization.CultureInfo;
@@ -59,10 +60,12 @@ public string? CultureName
public string? CodeBase
{
+ [RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
get => _codeBase;
set => _codeBase = value;
}
+ [RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
public string? EscapedCodeBase
{
get
@@ -258,6 +261,7 @@ public static bool ReferenceMatchesDefinition(AssemblyName? reference, AssemblyN
return refName.Equals(defName, StringComparison.OrdinalIgnoreCase);
}
+ [RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
internal static string EscapeCodeBase(string? codebase)
{
if (codebase == null)
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs
index dfa08abd5fc57..e990d5e491869 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs
@@ -609,6 +609,8 @@ public void Dispose()
return context.ResolveUsingLoad(assemblyName);
}
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "The code handles the Assembly.Location equals null")]
private Assembly? GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName)
{
Assembly? resolvedAssembly = null;
@@ -721,6 +723,8 @@ private static void OnAssemblyLoad(RuntimeAssembly assembly)
return InvokeResolveEvent(AssemblyResolve, assembly, assemblyFullName);
}
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "The code handles the Assembly.Location equals null")]
private static RuntimeAssembly? InvokeResolveEvent(ResolveEventHandler? eventHandler, RuntimeAssembly assembly, string name)
{
if (eventHandler == null)
@@ -752,6 +756,8 @@ private static void OnAssemblyLoad(RuntimeAssembly assembly)
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "Satellite assemblies have no code in them and loading is not a problem")]
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "This call is fine because native call runs before this and checks BindSatelliteResourceFromBundle")]
private Assembly? ResolveSatelliteAssembly(AssemblyName assemblyName)
{
// Called by native runtime when CultureName is not empty
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs
index a3b6334d08b5f..6fd1d1c83e81a 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs
@@ -140,6 +140,9 @@ internal void InitAssemblyMethods(XmlMapping[] xmlMappings)
// SxS: This method does not take any resource name and does not expose any resources to the caller.
// It's OK to suppress the SxS warning.
[RequiresUnreferencedCode("calls LoadFile")]
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "Annotating this as dangerous will make the core of the serializer to be marked as not safe, instead " +
+ "this pattern is only dangerous if using sgen only. See https://github.com/dotnet/runtime/issues/50820")]
internal static Assembly? LoadGeneratedAssembly(Type type, string? defaultNamespace, out XmlSerializerImplementation? contract)
{
Assembly? serializer = null;
diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs
index 2e6ecc3d16d6d..9241eadc04026 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs
@@ -629,6 +629,8 @@ private static XmlSerializer[] GetReflectionBasedSerializers(XmlMapping[] mappin
}
[RequiresUnreferencedCode("calls GenerateSerializerToStream")]
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "Code is used on diagnostics so we fallback to print assembly.FullName if assembly.Location is empty")]
internal static bool GenerateSerializer(Type[]? types, XmlMapping[] mappings, Stream stream)
{
if (types == null || types.Length == 0)
@@ -660,7 +662,10 @@ internal static bool GenerateSerializer(Type[]? types, XmlMapping[] mappings, St
}
else if (type.Assembly != assembly)
{
- throw new ArgumentException(SR.Format(SR.XmlPregenOrphanType, type.FullName, assembly.Location), nameof(types));
+ string? nameOrLocation = assembly.Location;
+ if (nameOrLocation == string.Empty)
+ nameOrLocation = assembly.FullName;
+ throw new ArgumentException(SR.Format(SR.XmlPregenOrphanType, type.FullName, nameOrLocation), nameof(types));
}
}
diff --git a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj
index 8ca7664c3e265..09daf8ff6c46d 100644
--- a/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj
+++ b/src/libraries/System.Reflection.Context/src/System.Reflection.Context.csproj
@@ -63,5 +63,6 @@
+
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs
index 689c85667228d..64c98012957c7 100644
--- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs
+++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Delegation/DelegatingAssembly.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Security;
@@ -21,6 +22,7 @@ public DelegatingAssembly(Assembly assembly)
UnderlyingAssembly = assembly;
}
+ [RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3000")]
public override string Location
{
get { return UnderlyingAssembly.Location; }
@@ -98,16 +100,19 @@ public override Type[] GetExportedTypes()
return UnderlyingAssembly.GetExportedTypes();
}
+ [RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFile(string)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream GetFile(string name)
{
return UnderlyingAssembly.GetFile(name);
}
+ [RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream[] GetFiles()
{
return UnderlyingAssembly.GetFiles();
}
+ [RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFiles(bool)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream[] GetFiles(bool getResourceModules)
{
return UnderlyingAssembly.GetFiles(getResourceModules);
diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj
index bf769cd262db5..d021572a0e0c3 100644
--- a/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj
+++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj
@@ -155,11 +155,17 @@
+
+
+
+
+
+
diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/Ecma/EcmaAssembly.Modules.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/Ecma/EcmaAssembly.Modules.cs
index 1866969c819de..c7cb4bd3143d8 100644
--- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/Ecma/EcmaAssembly.Modules.cs
+++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Assemblies/Ecma/EcmaAssembly.Modules.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
@@ -32,6 +33,8 @@ protected sealed override RoModule LoadModule(string moduleName, bool containsMe
throw new FileNotFoundException(SR.Format(SR.FileNotFoundModule, moduleName));
}
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "The code has a fallback using a ModuleResolveEventHandler")]
private FileStream? FindModuleNextToAssembly(string moduleName)
{
Assembly containingAssembly = this;
diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/RuntimeEnvironment.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
index 18b4113958cb3..5c4c8c7e53771 100644
--- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
+++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
@@ -13,6 +14,8 @@ public static class RuntimeEnvironment
public static bool FromGlobalAccessCache(Assembly a) => false;
+ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
+ Justification = "This call is fine because the code handles the Assembly.Location equals null by calling AppDomain.CurrentDomain.BaseDirectory")]
public static string GetRuntimeDirectory()
{
string? runtimeDirectory = typeof(object).Assembly.Location;
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index 12c4068842242..6ee3ca727a64b 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -7885,11 +7885,13 @@ public abstract partial class Assembly : System.Reflection.ICustomAttributeProvi
{
protected Assembly() { }
[System.ObsoleteAttribute("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
+ [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message="The code will throw for assemblies embedded in a single-file app")]
public virtual string? CodeBase { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable CustomAttributes { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } }
[System.ObsoleteAttribute("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
+ [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message="The code will throw for assemblies embedded in a single-file app")]
public virtual string EscapedCodeBase { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
public virtual string? FullName { get { throw null; } }
@@ -7924,6 +7926,7 @@ public virtual event System.Reflection.ModuleResolveEventHandler? ModuleResolve
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type[] GetExportedTypes() { throw null; }
public virtual System.IO.FileStream? GetFile(string name) { throw null; }
+ [System.Diagnostics.CodeAnalysis.RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual System.IO.FileStream[] GetFiles() { throw null; }
public virtual System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
@@ -8092,10 +8095,11 @@ public sealed partial class AssemblyName : System.ICloneable, System.Runtime.Ser
{
public AssemblyName() { }
public AssemblyName(string assemblyName) { }
- public string? CodeBase { get { throw null; } set { } }
+ public string? CodeBase { [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "The code will return an empty string for assemblies embedded in a single-file app")] get { throw null; } set { } }
public System.Reflection.AssemblyContentType ContentType { get { throw null; } set { } }
public System.Globalization.CultureInfo? CultureInfo { get { throw null; } set { } }
public string? CultureName { get { throw null; } set { } }
+ [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message="The code will return an empty string for assemblies embedded in a single-file app")]
public string? EscapedCodeBase { get { throw null; } }
public System.Reflection.AssemblyNameFlags Flags { get { throw null; } set { } }
public string FullName { get { throw null; } }
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 5530af517ee69..82fb892cb7064 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -357,6 +357,7 @@
+
diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs
index 0a32cc96c3e78..73de23d6fcc42 100644
--- a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs
+++ b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -210,6 +211,8 @@ private static async Task> ResolveIdentifiers(IEnumerable CompileAndRunTheExpression(string expression, MemberReferenceResolver resolver, CancellationToken token)
{
expression = expression.Trim();
diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj
index e7641b3ab1aad..23074621b8973 100644
--- a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj
+++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj
@@ -3,9 +3,9 @@
$(NetCoreAppToolCurrent);$(TargetFrameworkForNETFramework)
enable
$(NoWarn),CA1050
-
$(NoWarn),CS8604,CS8602
+ false