diff --git a/documentation/general/dotnet-run-file.md b/documentation/general/dotnet-run-file.md
index bdaf0176fdaa..9636bc0ff88b 100644
--- a/documentation/general/dotnet-run-file.md
+++ b/documentation/general/dotnet-run-file.md
@@ -52,6 +52,8 @@ Additionally, the implicit project file has the following customizations:
string? directoryPath = AppContext.GetData("EntryPointFileDirectoryPath") as string;
```
+ - `EntryPointFilePath` property is set to the entry-point file path and is made visible to analyzers via `CompilerVisibleProperty`.
+
- `FileBasedProgram` property is set to `true` and can be used by SDK targets to detect file-based apps.
- `DisableDefaultItemsInProjectFolder` property is set to `true` which results in `EnableDefaultItems=false` by default
@@ -270,6 +272,11 @@ Along with `#:`, the language also ignores `#!` which could be then used for [sh
Console.WriteLine("Hello");
```
+When a file-based program uses [`#:include`](#multiple-files) directives to include additional files,
+the entry point file should start with `#!` to clearly distinguish it from included files.
+This helps IDEs to properly handle multi-file scenarios and discover entry points.
+The analyzer **CA2266** reports a warning if the entry point file is missing the shebang line in this scenario.
+
## Implementation
The build is performed using MSBuild APIs on in-memory project files.
diff --git a/src/Cli/dotnet/Commands/Run/CSharpCompilerCommand.Generated.cs b/src/Cli/dotnet/Commands/Run/CSharpCompilerCommand.Generated.cs
index 147f81e8bfee..235b8ce8501b 100644
--- a/src/Cli/dotnet/Commands/Run/CSharpCompilerCommand.Generated.cs
+++ b/src/Cli/dotnet/Commands/Run/CSharpCompilerCommand.Generated.cs
@@ -165,6 +165,7 @@ private string GetGeneratedMSBuildEditorConfigContent()
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
+build_property.EntryPointFilePath = {EntryPointFileFullPath}
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = {FileNameWithoutExtension}
build_property.ProjectDir = {BaseDirectoryWithTrailingSeparator}
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.CSharp.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/CSharpMissingShebangInFileBasedProgram.Fixer.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.CSharp.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/CSharpMissingShebangInFileBasedProgram.Fixer.cs
new file mode 100644
index 000000000000..7894c0ab6c33
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.CSharp.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/CSharpMissingShebangInFileBasedProgram.Fixer.cs
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Composition;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Formatting;
+using Microsoft.NetCore.Analyzers;
+using Microsoft.NetCore.Analyzers.Usage;
+
+namespace Microsoft.NetCore.CSharp.Analyzers.Usage
+{
+ [ExportCodeFixProvider(LanguageNames.CSharp), Shared]
+ public sealed class CSharpMissingShebangInFileBasedProgramFixer : MissingShebangInFileBasedProgramFixer
+ {
+ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
+ if (root is null)
+ {
+ return;
+ }
+
+ var codeAction = CodeAction.Create(
+ MicrosoftNetCoreAnalyzersResources.MissingShebangInFileBasedProgramCodeFixTitle,
+ async ct =>
+ {
+ var options = await context.Document.GetOptionsAsync(ct).ConfigureAwait(false);
+ var eol = options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
+ var shebangTrivia = SyntaxFactory.ParseLeadingTrivia("#!/usr/bin/env dotnet" + eol);
+ var firstToken = root.GetFirstToken(includeZeroWidth: true);
+ var newFirstToken = firstToken.WithLeadingTrivia(shebangTrivia.AddRange(firstToken.LeadingTrivia));
+ var newRoot = root.ReplaceToken(firstToken, newFirstToken)
+ .WithAdditionalAnnotations(Formatter.Annotation);
+ return context.Document.WithSyntaxRoot(newRoot);
+ },
+ MicrosoftNetCoreAnalyzersResources.MissingShebangInFileBasedProgramCodeFixTitle);
+ context.RegisterCodeFix(codeAction, context.Diagnostics);
+ }
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.CSharp.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/CSharpMissingShebangInFileBasedProgram.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.CSharp.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/CSharpMissingShebangInFileBasedProgram.cs
new file mode 100644
index 000000000000..72966e162403
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.CSharp.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/CSharpMissingShebangInFileBasedProgram.cs
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using Analyzer.Utilities;
+using Analyzer.Utilities.Extensions;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.NetCore.Analyzers.Usage;
+
+namespace Microsoft.NetCore.CSharp.Analyzers.Usage
+{
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ public sealed class CSharpMissingShebangInFileBasedProgram : MissingShebangInFileBasedProgram
+ {
+ public override void Initialize(AnalysisContext context)
+ {
+ context.EnableConcurrentExecution();
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+
+ context.RegisterCompilationStartAction(context =>
+ {
+ var entryPointFilePath = context.Options.GetMSBuildPropertyValue(
+ MSBuildPropertyOptionNames.EntryPointFilePath, context.Compilation);
+ if (string.IsNullOrEmpty(entryPointFilePath))
+ {
+ return;
+ }
+
+ // Count non-generated trees upfront so we can report directly
+ // from a SyntaxTreeAction without needing CompilationEnd.
+ // We avoid CompilationEnd so diagnostics appear as live IDE diagnostics.
+ // We replicate Roslyn's generated code detection here because
+ // Compilation.SyntaxTrees is the raw set (unlike RegisterSyntaxTreeAction
+ // which gets automatic filtering via ConfigureGeneratedCodeAnalysis).
+ int nonGeneratedTreeCount = 0;
+ foreach (var tree in context.Compilation.SyntaxTrees)
+ {
+ if (IsGeneratedCode(tree, context.Options.AnalyzerConfigOptionsProvider))
+ {
+ continue;
+ }
+
+ nonGeneratedTreeCount++;
+ }
+
+ // Only report when there are multiple non-generated files
+ // (i.e., #:include directives are used).
+ // Single-file programs don't need a shebang to distinguish the entry point.
+ if (nonGeneratedTreeCount <= 1)
+ {
+ return;
+ }
+
+ context.RegisterSyntaxTreeAction(context =>
+ {
+ if (!context.Tree.FilePath.Equals(entryPointFilePath, StringComparison.Ordinal))
+ {
+ return;
+ }
+
+ var root = context.Tree.GetRoot(context.CancellationToken);
+ if (root.GetLeadingTrivia().Any(SyntaxKind.ShebangDirectiveTrivia))
+ {
+ return;
+ }
+
+ var location = root.GetFirstToken(includeZeroWidth: true).GetLocation();
+ context.ReportDiagnostic(location.CreateDiagnostic(Rule));
+ });
+ });
+ }
+
+ ///
+ /// Replicates Roslyn's generated code detection which checks:
+ /// the generated_code analyzer config option,
+ /// common file name patterns, and <auto-generated> comment headers.
+ ///
+ private static bool IsGeneratedCode(SyntaxTree tree, AnalyzerConfigOptionsProvider optionsProvider)
+ {
+ if (optionsProvider.GetOptions(tree)
+ .TryGetValue("generated_code", out var generatedValue) &&
+ generatedValue.Equals("true", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ var filePath = tree.FilePath;
+ if (!string.IsNullOrEmpty(filePath))
+ {
+ var fileName = Path.GetFileName(filePath);
+ if (fileName.StartsWith("TemporaryGeneratedFile_", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ var nameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
+ if (nameWithoutExtension.EndsWith(".designer", StringComparison.OrdinalIgnoreCase) ||
+ nameWithoutExtension.EndsWith(".generated", StringComparison.OrdinalIgnoreCase) ||
+ nameWithoutExtension.EndsWith(".g", StringComparison.OrdinalIgnoreCase) ||
+ nameWithoutExtension.EndsWith(".g.i", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ }
+
+ // Check for or comment at the top of the file.
+ foreach (var trivia in tree.GetRoot().GetLeadingTrivia())
+ {
+ switch (trivia.Kind())
+ {
+ case SyntaxKind.SingleLineCommentTrivia:
+ case SyntaxKind.MultiLineCommentTrivia:
+ var text = trivia.ToString();
+ if (text.Contains("Replace obsolete call
+
+ File-based program entry point should start with '#!'
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+ File-based program entry point should start with '#!'
+
+
+ Add '#!' (shebang)
+
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgram.Fixer.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgram.Fixer.cs
new file mode 100644
index 000000000000..0e2284174d9c
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgram.Fixer.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis.CodeFixes;
+
+namespace Microsoft.NetCore.Analyzers.Usage
+{
+ public abstract class MissingShebangInFileBasedProgramFixer : CodeFixProvider
+ {
+ public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(MissingShebangInFileBasedProgram.RuleId);
+
+ public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgram.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgram.cs
new file mode 100644
index 000000000000..938e7ce7c00f
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgram.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Collections.Immutable;
+using Analyzer.Utilities;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace Microsoft.NetCore.Analyzers.Usage
+{
+ using static MicrosoftNetCoreAnalyzersResources;
+
+ public abstract class MissingShebangInFileBasedProgram : DiagnosticAnalyzer
+ {
+ internal const string RuleId = "CA2266";
+
+ internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create(
+ RuleId,
+ CreateLocalizableResourceString(nameof(MissingShebangInFileBasedProgramTitle)),
+ CreateLocalizableResourceString(nameof(MissingShebangInFileBasedProgramMessage)),
+ DiagnosticCategory.Usage,
+ RuleLevel.BuildWarning,
+ CreateLocalizableResourceString(nameof(MissingShebangInFileBasedProgramDescription)),
+ isPortedFxCopRule: false,
+ isDataflowRule: false,
+ isReportedAtCompilationEnd: false);
+
+ public sealed override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
index d5f92baf02e5..03f1e965d7b2 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
@@ -1833,6 +1833,26 @@ Rozšíření a uživatelem definované převody se u obecných typů nepodporuj
Metoda akce {0} musí explicitně určit druh požadavku HTTP.
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Inicializátory modulů jsou určeny pro použití kódem aplikace k zajištění, aby byly komponenty aplikace inicializovány před tím, než se začne kód aplikace spouštět. Pokud kód knihovny deklaruje metodu s ModuleInitializerAttribute, může narušovat inicializaci aplikace a také vést k omezením schopností oříznutí dané aplikace. Knihovna by proto neměla používat metody s označením ModuleInitializerAttribute, ale namísto toho by měla zpřístupnit metody, které lze použít k inicializaci všech komponent v rámci knihovny a umožnit aplikaci vyvolat metodu během inicializace aplikace.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
index f63f006d064d..cbc4ff561ee1 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
@@ -1833,6 +1833,26 @@ Erweiterungen und benutzerdefinierte Konvertierungen werden bei generischen Type
Die Aktionsmethode "{0}" muss die Art der HTTP-Anforderung explizit angeben.
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Modulinitialisierer sollen vom Anwendungscode verwendet werden, um sicherzustellen, dass die Komponenten einer Anwendung initialisiert werden, bevor der Anwendungscode ausgeführt wird. Wenn Bibliothekscode eine Methode mit \"ModuleInitializerAttribute\" deklariert, kann dies die Anwendungsinitialisierung beeinträchtigen und auch zu Einschränkungen in den Kürzungsfähigkeiten dieser Anwendung führen. Anstatt Methoden zu verwenden, die mit \"ModuleInitializerAttribute\" gekennzeichnet sind, sollte die Bibliothek Methoden verfügbar machen, mit denen alle Komponenten innerhalb der Bibliothek initialisiert werden können, und der Anwendung das Aufrufen der Methode während der Anwendungsinitialisierung ermöglichen.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
index a03a7a0fa4d0..5896354af2af 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
@@ -1833,6 +1833,26 @@ La ampliación y las conversiones definidas por el usuario no se admiten con tip
El método de acción {0} debe especificar la variante de solicitud HTTP de forma explícita.
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Los inicializadores de módulo están diseñados para que los use el código de aplicación para asegurarse de que los componentes de una aplicación se inicializan antes de que el código de la aplicación comience a ejecutarse. Si el código de biblioteca declara un método con \"ModuleInitializerAttribute\", puede interferir con la inicialización de la aplicación y también provocar limitaciones en las capacidades de recorte de esa aplicación. En lugar de usar métodos marcados con \"ModuleInitializerAttribute\", la biblioteca debe exponer métodos que se pueden usar para inicializar cualquier componente dentro de la biblioteca y permitir que la aplicación invoque el método durante la inicialización de la aplicación.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
index 40c160bb5b5f..bed19cb8e096 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
@@ -1833,6 +1833,26 @@ Les conversions étendues et définies par l’utilisateur ne sont pas prises en
La méthode d'action {0} doit spécifier explicitement le genre de requête HTTP
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Les initialiseurs de module sont destinés à être utilisés par le code d’application pour s’assurer que les composants d’une application sont initialisés avant le début de l’exécution du code d’application. Si le code de bibliothèque déclare une méthode avec « ModuleInitializerAttribute », il peut interférer avec l’initialisation de l’application et également entraîner des limitations dans les capacités de découpage de cette application. Au lieu d’utiliser des méthodes marquées avec « ModuleInitializerAttribute », la bibliothèque doit exposer des méthodes qui peuvent être utilisées pour initialiser tous les composants de la bibliothèque et permettre à l’application d’appeler la méthode pendant l’initialisation de l’application.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
index 924a482d9f5d..ea2f9539b9a1 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
@@ -1833,6 +1833,26 @@ L'ampliamento e le conversioni definite dall'utente non sono supportate con tipi
Il metodo di azione {0} deve specificare in modo esplicito il tipo della richiesta HTTP
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.La presenza di inizializzatori di modulo nel codice dell'applicazione assicura che i componenti di un'applicazione vengano inizializzati prima dell'inizio dell'esecuzione del codice dell'applicazione. La dichiarazione di un modulo 'ModuleInitializerAttribute' nel codice della libreria può interferire con l'inizializzazione dell'applicazione e causare limitazioni alle funzionalità di trimming di tale applicazione. Il codice della libreria non deve quindi utilizzare l'attributo 'ModuleInitializerAttribute', ma esporre metodi utilizzabili per inizializzare tutti i componenti nella libreria e consentire all'applicazione di richiamare il metodo durante l'inizializzazione dell'applicazione.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
index 6c3fbfeccd9a..f37c847af7f9 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
@@ -1833,6 +1833,26 @@ Enumerable.OfType<T> で使用されるジェネリック型チェック (
アクション メソッド {0} では、HTTP 要求の種類を明示的に指定する必要があります
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.モジュール初期化子は、アプリケーション コードの実行を開始する前にアプリケーションのコンポーネントが初期化されるように、アプリケーション コードによって使用されることを目的としています。ライブラリ コードで 'ModuleInitializerAttribute' を使用してメソッドを宣言する場合、アプリケーションの初期化を妨げる可能性があり、そのアプリケーションのトリミング機能の制限にもつながります。'ModuleInitializerAttribute' でマークされたメソッドを使用する代わりに、ライブラリ内のコンポーネントを初期化し、アプリケーションの初期化中にアプリケーションがメソッドを呼び出せるようにするために使用できるメソッドを公開する必要があります。
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
index f0706403c0d4..8575638e2767 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
@@ -1833,6 +1833,26 @@ Enumerable.OfType<T>에서 사용하는 제네릭 형식 검사(C# 'is'
작업 메서드 {0}은(는) HTTP 요청 종류를 명시적으로 지정해야 합니다.
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.모듈 이니셜라이저는 응용 프로그램 코드가 실행을 시작하기 전에 응용 프로그램의 구성 요소가 초기화되도록 응용 프로그램 코드에서 사용하기 위한 것입니다. 라이브러리 코드가 'ModuleInitializerAttribute'를 사용하여 메서드를 선언하면 응용 프로그램 초기화를 방해할 수 있으며 해당 응용 프로그램의 트리밍 기능에 제한이 생길 수도 있습니다. 'ModuleInitializerAttribute'로 표시된 메서드를 사용하는 대신 라이브러리는 라이브러리 내의 구성 요소를 초기화하는 데 사용할 수 있는 메서드를 노출하고 응용 프로그램 초기화 중에 응용 프로그램이 메서드를 호출할 수 있도록 해야 합니다.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
index 51f4dee3e919..0e7b13760bac 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
@@ -1833,6 +1833,26 @@ Konwersje poszerzane i zdefiniowane przez użytkownika nie są obsługiwane w pr
Metoda akcji {0} musi jawnie określać rodzaj żądania HTTP
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Inicjatory modułów są przeznaczone do użycia przez kod aplikacji w celu zapewnienia, że składniki aplikacji zostaną zainicjowane przed rozpoczęciem wykonywania kodu aplikacji. Jeśli kod biblioteki deklaruje metodę za pomocą atrybutu „ModuleInitializer”, może zakłócać inicjowanie aplikacji, a także prowadzić do ograniczeń w możliwościach przycinania tej aplikacji. Zamiast używać metod oznaczonych atrybutem „ModuleInitializer”, biblioteka powinna uwidaczniać metody, których można użyć do zainicjowania składników w bibliotece i umożliwienia aplikacji wywołania metody podczas inicjowania aplikacji.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf
index cb9dea8edaf1..a3fc46da599c 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf
@@ -1833,6 +1833,26 @@ As ampliação e conversões definidas pelo usuário não são compatíveis com
O método de ação {0} precisa especificar explicitamente o tipo de solicitação HTTP
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Os inicializadores de módulo devem ser usados pelo código do aplicativo para garantir que os componentes de um aplicativo sejam inicializados antes que o código do aplicativo comece a ser executado. Se o código da biblioteca declara um método com o 'ModuleInitializerAttribute', ele pode interferir na inicialização do aplicativo e também levar a limitações nas habilidades de corte do aplicativo. Ao invés de usar métodos marcados com 'ModuleInitializerAttribute', a biblioteca deve expor os métodos que podem ser usados para inicializar quaisquer componentes dentro da biblioteca e permitir que o aplicativo invoque o método durante a inicialização do aplicativo.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
index 57538a5cb231..e97cb8f514af 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
@@ -1833,6 +1833,26 @@ Widening and user defined conversions are not supported with generic types.В методе действия {0} необходимо явным образом указать тип HTTP-запроса/
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Инициализаторы модулей предназначены для использования кодом приложения, чтобы обеспечить инициализацию компонентов приложения до того, как код приложения начнет выполняться. Если код библиотеки объявляет метод с ''ModuleInitializerAttribute'', это может помешать инициализации приложения, а также привести к ограничениям возможностей обрезки этого приложения. Вместо использования методов, помеченных ''ModuleInitializerAttribute'', библиотека должна предоставлять методы, которые можно использовать для инициализации любых компонентов в библиотеке, и позволять приложению вызывать метод во время инициализации приложения.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
index de2ea9f502e1..095fec929995 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
@@ -1833,6 +1833,26 @@ Genel türlerde genişletme ve kullanıcı tanımlı dönüştürmeler desteklen
{0} eylem metodunun HTTP istek tipini açık olarak belirtmesi gerekir
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.Modül başlatıcılar, uygulama kodu yürütülmeye başlamadan önce uygulamanın bileşenlerinin başlatılmasını sağlamak için uygulama kodu tarafından kullanılmak içindir. Kitaplık kodu 'ModuleInitializerAttribute' öznitelikli bir yöntem bildirirse, uygulamanın başlatılmasına engel olabilir ve ayrıca bu uygulamanın kırpma becerileriyle ilgili sınırlamalara neden olabilir. Kitaplık, 'ModuleInitializerAttribute' özniteliği ile işaretli yöntemleri kullanmak yerine, içindeki bileşenlerin başlatılması için kullanılabilecek ve başlatılırken uygulamanın çağırabileceği yöntemleri kullanıma sunmalıdır.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf
index 68f722d64e4f..40cccfbb4381 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf
@@ -1833,6 +1833,26 @@ Enumerable.OfType<T> 使用的泛型类型检查(C# 'is' operator/IL 'isin
操作方法 {0} 需要显式指定 HTTP 请求类型
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.模块初始化表达式旨在由应用程序代码用于确保在应用程序代码开始执行之前初始化应用程序的组件。如果库代码使用 “ModuleInitializer” 声明方法,则可能干扰应用程序初始化,并且还会导致限制该应用程序的剪裁功能。因此库不应使用标记为 “ModuleInitializerAttribute” 的方法,而应公开可用于初始化库中任何组件的方法,并允许应用程序在应用程序初始化期间调用该方法。
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf
index 43db515c0d4b..0e95e70cea6b 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf
@@ -1833,6 +1833,26 @@ Enumerable.OfType<T> 使用的一般型別檢查 (C# 'is' operator/IL 'isi
Action 方法 {0} 必須明確地指定 HTTP 要求種類
+
+ Add '#!' (shebang)
+ Add '#!' (shebang)
+
+
+
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+ When a file-based program consists of multiple files, the entry point file should start with a shebang ('#!') line to clearly distinguish it from other included files.
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+
+
+ File-based program entry point should start with '#!'
+ File-based program entry point should start with '#!'
+
+ Module initializers are intended to be used by application code to ensure an application's components are initialized before the application code begins executing. If library code declares a method with the 'ModuleInitializerAttribute', it can interfere with application initialization and also lead to limitations in that application's trimming abilities. Instead of using methods marked with 'ModuleInitializerAttribute', the library should expose methods that can be used to initialize any components within the library and allow the application to invoke the method during application initialization.模組初始設定式供應用程式程式碼使用,以確保應用程式程式碼開始執行前先初始化應用程式的元件。如果程式庫程式碼宣告擁有 'ModuleInitializerAttribute' 的方法,它可能會干擾應用程式初始化,而且也會導致該應用程式的截斷功能遭到限制。不使用標示為 'ModuleInitializerAttribute' 的方法,程式庫應該公開可用於初始化程式庫內任何元件的方法,並允許應用程式在應用程式初始化期間叫用方法。
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
index 84d171e834bd..c22f1703c19a 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
@@ -14,7 +14,7 @@ Globalization: CA2101, CA1300-CA1311
Mobility: CA1600-CA1601
Performance: HA, CA1800-CA1875
Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5405
-Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2265
+Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2266
Naming: CA1700-CA1727
Interoperability: CA1400-CA1422
Maintainability: CA1500-CA1515
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/Options/MSBuildPropertyOptionNames.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/Options/MSBuildPropertyOptionNames.cs
index 314f1ec6d51b..0d7db6ee7732 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/Options/MSBuildPropertyOptionNames.cs
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/Options/MSBuildPropertyOptionNames.cs
@@ -23,6 +23,7 @@ internal static class MSBuildPropertyOptionNames
public const string InvariantGlobalization = nameof(InvariantGlobalization);
public const string PlatformNeutralAssembly = nameof(PlatformNeutralAssembly);
public const string EnforceExtendedAnalyzerRules = nameof(EnforceExtendedAnalyzerRules);
+ public const string EntryPointFilePath = nameof(EntryPointFilePath);
}
internal static class MSBuildPropertyOptionNamesHelpers
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgramTests.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgramTests.cs
new file mode 100644
index 000000000000..120290e0f55a
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Usage/MissingShebangInFileBasedProgramTests.cs
@@ -0,0 +1,160 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Testing;
+using VerifyCS = Test.Utilities.CSharpSecurityCodeFixVerifier<
+ Microsoft.NetCore.CSharp.Analyzers.Usage.CSharpMissingShebangInFileBasedProgram,
+ Microsoft.NetCore.CSharp.Analyzers.Usage.CSharpMissingShebangInFileBasedProgramFixer>;
+
+namespace Microsoft.NetCore.Analyzers.Usage.UnitTests
+{
+ public class MissingShebangInFileBasedProgramTests
+ {
+ private const string GlobalConfig = "is_global = true\r\nbuild_property.EntryPointFilePath = Test0.cs";
+
+ [Fact]
+ public async Task EntryPointWithoutShebang_MultipleFiles_WarningAsync()
+ {
+ // Entry point file without shebang, multiple files - warning expected.
+ await new VerifyCS.Test
+ {
+ TestState =
+ {
+ Sources =
+ {
+ ("Test0.cs", """class Program { static void Main() { } }"""),
+ ("Util.cs", """class Util { public static string Greet() => "hello"; }"""),
+ },
+ AnalyzerConfigFiles = { ("/.globalconfig", GlobalConfig) },
+ ExpectedDiagnostics =
+ {
+ new DiagnosticResult(MissingShebangInFileBasedProgram.Rule).WithLocation("Test0.cs", 1, 1),
+ },
+ },
+ }.RunAsync();
+ }
+
+ [Fact]
+ public async Task NoEntryPointFilePath_NoDiagnosticAsync()
+ {
+ // No EntryPointFilePath - not a file-based program, no diagnostic.
+ await VerifyCS.VerifyAnalyzerAsync("""
+ class Program
+ {
+ static void Main()
+ {
+ System.Console.WriteLine("hello");
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task SingleFile_NoDiagnosticAsync()
+ {
+ // Single file - no need to distinguish entry point, no diagnostic.
+ await new VerifyCS.Test
+ {
+ TestState =
+ {
+ Sources = { ("Test0.cs", """class Program { static void Main() { } }""") },
+ AnalyzerConfigFiles = { ("/.globalconfig", GlobalConfig) },
+ },
+ }.RunAsync();
+ }
+
+ [Fact]
+ public async Task EntryPointWithoutShebang_CodeFixAddsShebangAsync()
+ {
+ // Verify that the code fix prepends a shebang line.
+ await new VerifyCS.Test
+ {
+ TestState =
+ {
+ Sources =
+ {
+ ("Test0.cs", """class Program { static void Main() { } }"""),
+ ("Util.cs", """class Util { public static string Greet() => "hello"; }"""),
+ },
+ AnalyzerConfigFiles = { ("/.globalconfig", GlobalConfig) },
+ ExpectedDiagnostics =
+ {
+ new DiagnosticResult(MissingShebangInFileBasedProgram.Rule).WithLocation("Test0.cs", 1, 1),
+ },
+ },
+ FixedState =
+ {
+ Sources =
+ {
+ ("Test0.cs", """
+ #!/usr/bin/env dotnet
+ class Program { static void Main() { } }
+ """),
+ ("Util.cs", """class Util { public static string Greet() => "hello"; }"""),
+ },
+ },
+ CodeFixTestBehaviors = CodeFixTestBehaviors.SkipLocalDiagnosticCheck,
+ SolutionTransforms =
+ {
+ (solution, projectId) =>
+ {
+ // Enable #! shebang support in the parser.
+ var parseOptions = (CSharpParseOptions)solution.GetProject(projectId)!.ParseOptions!;
+ return solution.WithProjectParseOptions(projectId,
+ parseOptions.WithFeatures(parseOptions.Features.Concat(
+ [new KeyValuePair("FileBasedProgram", "true")])));
+ },
+ },
+ }.RunAsync();
+ }
+
+ [Fact]
+ public async Task EntryPointWithShebang_MultipleFiles_NoDiagnosticAsync()
+ {
+ // Entry point already has shebang, multiple files - no diagnostic.
+ await new VerifyCS.Test
+ {
+ TestState =
+ {
+ Sources =
+ {
+ ("Test0.cs", """
+ #!/usr/bin/env dotnet
+ class Program { static void Main() { } }
+ """),
+ ("Util.cs", """class Util { public static string Greet() => "hello"; }"""),
+ },
+ AnalyzerConfigFiles = { ("/.globalconfig", GlobalConfig) },
+ },
+ SolutionTransforms =
+ {
+ (solution, projectId) =>
+ {
+ var parseOptions = (CSharpParseOptions)solution.GetProject(projectId)!.ParseOptions!;
+ return solution.WithProjectParseOptions(projectId,
+ parseOptions.WithFeatures(parseOptions.Features.Concat(
+ [new KeyValuePair("FileBasedProgram", "true")])));
+ },
+ },
+ }.RunAsync();
+ }
+
+ [Fact]
+ public async Task EmptyEntryPointFilePath_NoDiagnosticAsync()
+ {
+ // Empty EntryPointFilePath - not a file-based program, no diagnostic.
+ await new VerifyCS.Test
+ {
+ TestState =
+ {
+ Sources =
+ {
+ ("Test0.cs", """class Program { static void Main() { } }"""),
+ ("Util.cs", """class Util { }"""),
+ },
+ AnalyzerConfigFiles = { ("/.globalconfig", "is_global = true\r\nbuild_property.EntryPointFilePath = ") },
+ },
+ }.RunAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.DotNet.ProjectTools/VirtualProjectBuilder.cs b/src/Microsoft.DotNet.ProjectTools/VirtualProjectBuilder.cs
index 0c2950fa03df..b4adf03ea70c 100644
--- a/src/Microsoft.DotNet.ProjectTools/VirtualProjectBuilder.cs
+++ b/src/Microsoft.DotNet.ProjectTools/VirtualProjectBuilder.cs
@@ -499,6 +499,7 @@ internal static void WriteProjectFile(
artifacts/$(AssemblyName)artifacts/$(AssemblyName)true
+ {EscapeValue(entryPointFilePath)}{CSharpDirective.IncludeOrExclude.DefaultMappingString}falsetrue
diff --git a/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs b/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs
index 585e5ab925bc..8424e38ee8d0 100644
--- a/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs
+++ b/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Immutable;
@@ -1815,6 +1815,81 @@ public void Verbosity_CompilationDiagnostics()
.And.HaveStdErrContaining(CliCommandStrings.RunCommandException);
}
+ [Fact]
+ public void MissingShebangWarning()
+ {
+ var testInstance = _testAssetsManager.CreateTestDirectory();
+
+ File.WriteAllText(Path.Join(testInstance.Path, "Directory.Build.props"), """
+
+
+ true
+ true
+ preview
+
+
+ """);
+
+ // Single-file program without shebang should NOT produce CA2266
+ // (the warning only fires when there are multiple files via #:include).
+ File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """
+ Console.WriteLine("hello");
+ """);
+
+ new DotnetCommand(Log, "run", "Program.cs")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute()
+ .Should().Pass()
+ .And.NotHaveStdOutContaining("CA2266")
+ .And.HaveStdOutContaining("hello");
+
+ // Included file without shebang should not produce CA2266.
+ File.WriteAllText(Path.Join(testInstance.Path, "Util.cs"), """
+ class Util { public static string Greet() => "hello"; }
+ """);
+
+ // Entry point with shebang and #:include — no warning.
+ File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """
+ #!/usr/bin/env dotnet
+ #:include Util.cs
+ Console.WriteLine(Util.Greet());
+ """);
+
+ new DotnetCommand(Log, "run", "Program.cs")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute()
+ .Should().Pass()
+ .And.NotHaveStdOutContaining("CA2266")
+ .And.HaveStdOutContaining("hello");
+
+ // Entry point without shebang and #:include — CA2266 warning expected.
+ File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """
+ #:include Util.cs
+ Console.WriteLine(Util.Greet());
+ """);
+
+ new DotnetCommand(Log, "run", "Program.cs")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute()
+ .Should().Pass()
+ .And.HaveStdOutContaining("warning CA2266")
+ .And.HaveStdOutContaining("hello");
+
+ // CA2266 can be suppressed via NoWarn.
+ File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """
+ #:property NoWarn=CA2266
+ #:include Util.cs
+ Console.WriteLine(Util.Greet());
+ """);
+
+ new DotnetCommand(Log, "run", "Program.cs")
+ .WithWorkingDirectory(testInstance.Path)
+ .Execute()
+ .Should().Pass()
+ .And.NotHaveStdOutContaining("CA2266")
+ .And.HaveStdOutContaining("hello");
+ }
+
///
/// File-based projects using the default SDK do not include embedded resources by default.
///
@@ -5734,6 +5809,7 @@ public void Api()
artifacts/$(AssemblyName)artifacts/$(AssemblyName)true
+ {programPath}.cs=Compile;.resx=EmbeddedResource;.json=None;.razor=Contentfalsetrue
@@ -5826,6 +5902,7 @@ public void Api_Evaluation()
artifacts/$(AssemblyName)artifacts/$(AssemblyName)true
+ {programPath}.cs=Compile;.resx=EmbeddedResource;.json=None;.razor=Contentfalsetrue
@@ -5901,6 +5978,7 @@ public void Api_Diagnostic_01()
artifacts/$(AssemblyName)artifacts/$(AssemblyName)true
+ {programPath}.cs=Compile;.resx=EmbeddedResource;.json=None;.razor=Contentfalsetrue
@@ -5975,6 +6053,7 @@ public void Api_Diagnostic_02()
artifacts/$(AssemblyName)artifacts/$(AssemblyName)true
+ {programPath}.cs=Compile;.resx=EmbeddedResource;.json=None;.razor=Contentfalsetrue