diff --git a/README.md b/README.md index 41d0bcf3a..5934e8ce3 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,8 @@ If you are already using other analyzers, you can check [which rules are duplica |[MA0151](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0151.md)|Usage|DebuggerDisplay must contain valid members|⚠️|✔️|❌| |[MA0152](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0152.md)|Performance|Use Unwrap instead of using await twice|ℹ️|✔️|❌| |[MA0153](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0153.md)|Design|Do not log symbols decorated with DataClassificationAttribute directly|⚠️|✔️|❌| -|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|ℹ️|✔️|❌| +|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|ℹ️|✔️|✔️| +|[MA0155](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0155.md)|Usage|UseShellExecute must be explicitly set|⚠️|❌|❌| diff --git a/docs/README.md b/docs/README.md index e332969cd..b3842c964 100644 --- a/docs/README.md +++ b/docs/README.md @@ -153,7 +153,8 @@ |[MA0151](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0151.md)|Usage|DebuggerDisplay must contain valid members|⚠️|✔️|❌| |[MA0152](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0152.md)|Performance|Use Unwrap instead of using await twice|ℹ️|✔️|❌| |[MA0153](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0153.md)|Design|Do not log symbols decorated with DataClassificationAttribute directly|⚠️|✔️|❌| -|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|ℹ️|✔️|❌| +|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|ℹ️|✔️|✔️| +|[MA0155](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0155.md)|Usage|UseShellExecute must be explicitly set|⚠️|❌|❌| |Id|Suppressed rule|Justification| |--|---------------|-------------| @@ -622,6 +623,9 @@ dotnet_diagnostic.MA0153.severity = warning # MA0154: Use langword in XML comment dotnet_diagnostic.MA0154.severity = suggestion + +# MA0155: UseShellExecute must be explicitly set +dotnet_diagnostic.MA0155.severity = none ``` # .editorconfig - all rules disabled @@ -1085,4 +1089,7 @@ dotnet_diagnostic.MA0153.severity = none # MA0154: Use langword in XML comment dotnet_diagnostic.MA0154.severity = none + +# MA0155: UseShellExecute must be explicitly set +dotnet_diagnostic.MA0155.severity = none ``` diff --git a/docs/Rules/MA0155.md b/docs/Rules/MA0155.md new file mode 100644 index 000000000..ebb7636e6 --- /dev/null +++ b/docs/Rules/MA0155.md @@ -0,0 +1,43 @@ +# MA0155 - UseShellExecute must be explicitly set + +Detects when `Process.Start` is called without specifying the value of `UseShellExecute`. + +The goal is to help for those two cases: +- The default value for this property is true on .NET Framework apps and false on .NET Core apps. +- It must be set to to false when redirecting I/O. + + +````c# +using System.Diasgnostics; + +// Non compliant + +Process.Start("cmd"); // Intent is not clear if you want to use ShellExecute or not + +Process.Start("https://www.meziantou.net/"); // Will fail on .NET Core apps + +Process.Start(new ProcessStartInfo("cmd") +{ + RedirectStandardOutput = true, + UseShellExecute = true, +}); // It will throw with error "UseShellExecute must be set to false when redirecting I/O" + +Process.Start(new ProcessStartInfo("cmd") +{ + RedirectStandardOutput = true, +}); // It will throw with error "UseShellExecute must be set to false when redirecting I/O" on .NET Framework apps + +// Compliant + +Process.Start(new ProcessStartInfo("https://www.meziantou.net/") +{ + UseShellExecute = true, +}); + +Process.Start(new ProcessStartInfo("cmd") +{ + RedirectStandardOutput = true, + UseShellExecute = false, +}); + +```` \ No newline at end of file diff --git a/src/Meziantou.Analyzer/Rules/UseShellExecuteAnalyzer.cs b/src/Meziantou.Analyzer/Rules/UseShellExecuteAnalyzer.cs index 466efab4c..c7a5bb0ce 100644 --- a/src/Meziantou.Analyzer/Rules/UseShellExecuteAnalyzer.cs +++ b/src/Meziantou.Analyzer/Rules/UseShellExecuteAnalyzer.cs @@ -57,8 +57,11 @@ public override void Initialize(AnalysisContext context) ctx.RegisterOperationAction(analyzerContext.AnalyzeInvocation, OperationKind.Invocation); ctx.RegisterOperationAction(analyzerContext.AnalyzeObjectCreation, OperationKind.ObjectCreation); }); + } + + private sealed class AnalyzerContext(Compilation compilation) { private readonly INamedTypeSymbol? _processStartInfoSymbol = compilation.GetBestTypeByMetadataName("System.Diagnostics.ProcessStartInfo");