diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 77ac125..2f64659 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,18 +3,11 @@ "isRoot": true, "tools": { "jetbrains.dotcover.globaltool": { - "version": "2022.1.2", + "version": "2023.2.5", "commands": [ "dotnet-dotcover" ], "rollForward": false - }, - "dotnet-csi": { - "version": "1.0.7", - "commands": [ - "dotnet-csi" - ], - "rollForward": false } } } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 508e892..6cd42db 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ *.user .teamcity/target/ .reports/ +.packages \ No newline at end of file diff --git a/Build/Program.cs b/Build/Program.cs index f90d69e..630cbd0 100644 --- a/Build/Program.cs +++ b/Build/Program.cs @@ -134,7 +134,8 @@ .EnsureSuccess(); var dotCoverReportXml = Path.Combine(reportDir, "dotCover.xml"); - new DotNetCustom("dotCover", "report", $"--source={dotCoverSnapshot}", $"--output={dotCoverReportXml}", "--reportType=TeamCityXml").WithShortName("Generating the code coverage reports").Run().EnsureSuccess(); + new DotNetCustom("dotCover", "report", $"--source={dotCoverSnapshot}", $"--output={dotCoverReportXml}", "--reportType=TeamCityXml").WithShortName("Generating the code coverage reports") + .Run().EnsureSuccess(); if (TryGetCoverage(dotCoverReportXml, out coveragePercentage)) { @@ -176,20 +177,22 @@ var installTool = new DotNetCustom("tool", "install", toolPackageId, "-g", "--version", packageVersion.ToString(), "--add-source", Path.Combine(outputDir, "CSharpInteractive.Tool")) .WithShortName("Installing tool"); -if (installTool.Run(output => WriteLine(output.Line)).ExitCode != 0) +installTool.Run(output => { - Warning($"{installTool} failed."); -} + output.Handled = true; + WriteLine(output.Line); +}).EnsureSuccess(r => default); new DotNetCustom("csi", "/?").WithShortName("Checking tool").Run().EnsureSuccess(); var uninstallTemplates = new DotNetCustom("new", "uninstall", templatesPackageId) .WithShortName("Uninstalling template"); -if (uninstallTemplates.Run(output => WriteLine(output.Line)).ExitCode != 0) +uninstallTemplates.Run(output => { - Warning($"{uninstallTemplates} failed."); -} + output.Handled = true; + WriteLine(output.Line); +}).EnsureSuccess(r => default);; var installTemplates = new DotNetCustom("new", "install", $"{templatesPackageId}::{packageVersion.ToString()}", "--nuget-source", templateOutputDir) .WithShortName("Installing template"); @@ -204,10 +207,28 @@ try { var sampleProjectDir = Path.Combine("Samples", "MySampleLib", "MySampleLib.Tests"); - new DotNetNew("build", $"--package-version={packageVersion}", "-T", framework, "--no-restore").WithWorkingDirectory(buildProjectDir).WithShortName($"Creating a new {sampleProjectName}").Run().EnsureSuccess(); - new DotNetBuild().WithProject(buildProjectDir).WithSources(defaultNuGetSource, Path.Combine(outputDir, "CSharpInteractive")).WithShortName($"Building the {sampleProjectName}").Build().EnsureSuccess(); - new DotNetRun().WithProject(buildProjectDir).WithNoBuild(true).WithWorkingDirectory(sampleProjectDir).WithShortName($"Running a build for the {sampleProjectName}").Run().EnsureSuccess(); - new DotNetCustom("csi", Path.Combine(buildProjectDir, "Program.csx")).WithWorkingDirectory(sampleProjectDir).WithShortName($"Running a build as a C# script for the {sampleProjectName}").Run().EnsureSuccess(); + new DotNetNew("build", $"--package-version={packageVersion}", "-T", framework, "--no-restore") + .WithWorkingDirectory(buildProjectDir) + .WithShortName($"Creating a new {sampleProjectName}") + .Run().EnsureSuccess(); + + new DotNetBuild() + .WithProject(buildProjectDir) + .WithSources(defaultNuGetSource, Path.Combine(outputDir, "CSharpInteractive")) + .WithShortName($"Building the {sampleProjectName}") + .Build().EnsureSuccess(); + + new DotNetRun() + .WithProject(buildProjectDir) + .WithNoBuild(true) + .WithWorkingDirectory(sampleProjectDir) + .WithShortName($"Running a build for the {sampleProjectName}") + .Run().EnsureSuccess(); + + new DotNetCustom("csi", Path.Combine(buildProjectDir, "Program.csx")) + .WithWorkingDirectory(sampleProjectDir) + .WithShortName($"Running a build as a C# script for the {sampleProjectName}") + .Run().EnsureSuccess(); } finally { @@ -220,7 +241,9 @@ var push = new DotNetNuGetPush().WithApiKey(apiKey).WithSources(defaultNuGetSource); foreach (var package in packages.Where(i => i.Publish)) { - push.WithPackage(package.Package).WithShortName($"Pushing {Path.GetFileName(package.Package)}").Build().EnsureSuccess(); + push.WithPackage(package.Package) + .WithShortName($"Pushing {Path.GetFileName(package.Package)}") + .Build().EnsureSuccess(); } } else @@ -232,7 +255,9 @@ { var logicOp = integrationTests && dockerLinuxTests ? "|" : "&"; var filter = $"Integration={integrationTests}{logicOp}Docker={dockerLinuxTests}"; - test.WithFilter(filter).Build().EnsureSuccess(); + test + .WithFilter(filter) + .Build().EnsureSuccess(); } WriteLine("To use the csi tool:", Color.Highlighted); diff --git a/CSharpInteractive.HostApi/Internal/DotNet/DotNetCommandLineExtensions.cs b/CSharpInteractive.HostApi/Internal/DotNet/DotNetCommandLineExtensions.cs index 4e033f0..1a3a813 100644 --- a/CSharpInteractive.HostApi/Internal/DotNet/DotNetCommandLineExtensions.cs +++ b/CSharpInteractive.HostApi/Internal/DotNet/DotNetCommandLineExtensions.cs @@ -56,7 +56,7 @@ public static CommandLine AddMSBuildLoggers(this CommandLine cmd, IHost host, Do return settings.LoggersAreRequired ? cmd .AddArgs("/noconsolelogger") - .AddMSBuildArgs(("/l", $"TeamCity.MSBuild.Logger.TeamCityMSBuildLogger,{virtualContext.Resolve(settings.DotNetMSBuildLoggerDirectory)}/TeamCity.MSBuild.Logger.dll;TeamCity;plain")) + .AddMSBuildArgs(("/l", $"TeamCity.MSBuild.Logger.TeamCityMSBuildLogger,{virtualContext.Resolve(settings.DotNetMSBuildLoggerDirectory)}/TeamCity.MSBuild.Logger.dll;TEAMCITY;PLAIN;NOSUMMARY")) .AddProps("-p", ("VSTestLogger", TeamcityLoggerName), ("VSTestTestAdapterPath", virtualContext.Resolve(settings.DotNetVSTestLoggerDirectory)), diff --git a/CSharpInteractive.Templates/CSharpInteractive.Templates.csproj b/CSharpInteractive.Templates/CSharpInteractive.Templates.csproj index 2fc55f3..9464478 100644 --- a/CSharpInteractive.Templates/CSharpInteractive.Templates.csproj +++ b/CSharpInteractive.Templates/CSharpInteractive.Templates.csproj @@ -15,6 +15,7 @@ C# script Templates $(Company) $(Title) $(Version) $(TargetFramework) Template + content/ConsoleApplication-CSharp/README.md True diff --git a/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.cs b/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.cs index 6395150..c85084f 100644 --- a/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.cs +++ b/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.cs @@ -1,4 +1,4 @@ using HostApi; -// Builds a dotnet solution or project -return new DotNetBuild().Build().ExitCode ?? 1; \ No newline at end of file +// Build a dotnet solution or project +new DotNetBuild().Build().EnsureSuccess(); \ No newline at end of file diff --git a/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.csx b/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.csx index f356fad..bd3b47d 100644 --- a/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.csx +++ b/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/Program.csx @@ -14,10 +14,11 @@ // To add an assembly reference: // #r "MyAssembly.dll" -// To include code from the file in the order in which it should be executed: +// To include code from the file +// in the order in which it should be executed: // #load "MyClass.cs" // More information can be found on the page: // https://github.com/DevTeam/csharp-interactive -#load "Program.cs" \ No newline at end of file +#load "Program.cs" diff --git a/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/README.md b/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/README.md new file mode 100644 index 0000000..0ebd6b7 --- /dev/null +++ b/CSharpInteractive.Templates/content/ConsoleApplication-CSharp/README.md @@ -0,0 +1,23 @@ +Install the C# script template [CSharpInteractive.Templates](https://www.nuget.org/packages/CSharpInteractive.Templates) + +```shell +dotnet new -i CSharpInteractive.Templates +``` + +Create a console project "Build" containing a script from the template *__build__* + +```shell +dotnet new build -o ./Build +``` + +This projects contains the script *__./Build/Program.csx__*. To run this script from the command line from the directory *__Build__*: + +```shell +dotnet csi Build +``` + +To run as a .NET console application: + +```shell +dotnet run --project Build +``` diff --git a/CSharpInteractive.Tests/README_TEMPLATE.md b/CSharpInteractive.Tests/README_TEMPLATE.md index f3734e8..68e3291 100644 --- a/CSharpInteractive.Tests/README_TEMPLATE.md +++ b/CSharpInteractive.Tests/README_TEMPLATE.md @@ -123,9 +123,8 @@ public void Run() private class MyTask(ICommandLineRunner runner) { - public int? Run() => - runner.Run(new CommandLine("whoami")); + runner.Run(new CommandLine("whoami")).ExitCode; } ``` @@ -256,22 +255,18 @@ cmd = new CommandLine("cmd", "/c", "echo", "Hello") // Adds the namespace "HostApi" to use Command Line API using HostApi; -var exitCode = GetService().Run(new CommandLine("cmd", "/c", "DIR")); -exitCode.ShouldBe(0); +GetService().Run(new CommandLine("cmd", "/c", "DIR")).EnsureSuccess(); // or the same thing using the extension method -exitCode = new CommandLine("cmd", "/c", "DIR").Run(); -exitCode.ShouldBe(0); +new CommandLine("cmd", "/c", "DIR").Run().EnsureSuccess(); // using operator '+' var cmd = new CommandLine("cmd") + "/c" + "DIR"; -exitCode = cmd.Run(); -exitCode.ShouldBe(0); +cmd.Run().EnsureSuccess(); // with environment variables cmd = new CommandLine("cmd") + "/c" + "DIR" + ("MyEnvVar", "Some Value"); -exitCode = cmd.Run(); -exitCode.ShouldBe(0); +cmd.Run().EnsureSuccess(); ``` @@ -284,10 +279,10 @@ exitCode.ShouldBe(0); // Adds the namespace "HostApi" to use Command Line API using HostApi; -int? exitCode = await GetService().RunAsync(new CommandLine("cmd", "/C", "DIR")); +var task = await GetService().RunAsync(new CommandLine("cmd", "/C", "DIR")); // or the same thing using the extension method -exitCode = await new CommandLine("cmd", "/c", "DIR").RunAsync(); +task = await new CommandLine("cmd", "/c", "DIR").RunAsync(); ``` @@ -303,7 +298,7 @@ using HostApi; var lines = new List(); int? exitCode = new CommandLine("cmd", "/c", "SET") .AddVars(("MyEnv", "MyVal")) - .Run(output => lines.Add(output.Line)); + .Run(output => lines.Add(output.Line)).ExitCode; lines.ShouldContain("MyEnv=MyVal"); ``` @@ -318,8 +313,8 @@ lines.ShouldContain("MyEnv=MyVal"); // Adds the namespace "HostApi" to use Command Line API using HostApi; -Task task = new CommandLine("cmd", "/c", "DIR").RunAsync(); -int? exitCode = new CommandLine("cmd", "/c", "SET").Run(); +var task = new CommandLine("cmd", "/c", "DIR").RunAsync(); +var result = new CommandLine("cmd", "/c", "SET").Run(); task.Wait(); ``` @@ -334,7 +329,7 @@ The cancellation will kill a related process. using HostApi; var cancellationTokenSource = new CancellationTokenSource(); -Task task = new CommandLine("cmd", "/c", "TIMEOUT", "/T", "120").RunAsync(default, cancellationTokenSource.Token); +var task = new CommandLine("cmd", "/c", "TIMEOUT", "/T", "120").RunAsync(default, cancellationTokenSource.Token); cancellationTokenSource.CancelAfter(TimeSpan.FromMilliseconds(100)); task.IsCompleted.ShouldBeFalse(); @@ -350,7 +345,7 @@ If timeout expired a process will be killed. // Adds the namespace "HostApi" to use Command Line API using HostApi; -int? exitCode = new CommandLine("cmd", "/c", "TIMEOUT", "/T", "120").Run(default, TimeSpan.FromMilliseconds(1)); +int? exitCode = new CommandLine("cmd", "/c", "TIMEOUT", "/T", "120").Run(default, TimeSpan.FromMilliseconds(1)).ExitCode; exitCode.HasValue.ShouldBeFalse(); ``` @@ -420,9 +415,10 @@ using HostApi; // Gets the dotnet version, running a command like: "dotnet --version" NuGetVersion? version = default; -var exitCode = new DotNetCustom("--version").Run(message => NuGetVersion.TryParse(message.Line, out version)); +var exitCode = new DotNetCustom("--version") + .Run(message => NuGetVersion.TryParse(message.Line, out version)) + .EnsureSuccess(); -exitCode.ShouldBe(0); version.ShouldNotBeNull(); ``` @@ -569,17 +565,16 @@ result.Tests.Count(test => test.State == TestState.Finished).ShouldBe(1); using HostApi; // Creates a new test project, running a command like: "dotnet new mstest -n MyTests --force" -var exitCode = new DotNetNew("mstest", "-n", "MyTests", "--force").Run(); -exitCode.ShouldBe(0); +new DotNetNew("mstest", "-n", "MyTests", "--force") + .Run().EnsureSuccess(); // Creates the tool manifest and installs the dotCover tool locally // It is better to run the following 2 commands manually // and commit these changes to a source control -exitCode = new DotNetNew("tool-manifest").Run(); -exitCode.ShouldBe(0); +new DotNetNew("tool-manifest").Run().EnsureSuccess(); -exitCode = new DotNetCustom("tool", "install", "--local", "JetBrains.dotCover.GlobalTool").Run(); -exitCode.ShouldBe(0); +new DotNetCustom("tool", "install", "--local", "JetBrains.dotCover.GlobalTool") + .Run().EnsureSuccess(); // Creates a test command var test = new DotNetTest().WithProject("MyTests"); @@ -605,8 +600,8 @@ result.ExitCode.ShouldBe(0); result.Tests.Count(i => i.State == TestState.Finished).ShouldBe(1); // Generates a HTML code coverage report. -exitCode = new DotNetCustom("dotCover", "report", $"--source={dotCoverSnapshot}", $"--output={dotCoverReport}", "--reportType=HTML").Run(); -exitCode.ShouldBe(0); +new DotNetCustom("dotCover", "report", $"--source={dotCoverSnapshot}", $"--output={dotCoverReport}", "--reportType=HTML") + .Run().EnsureSuccess(); // Check for a dotCover report File.Exists(dotCoverReport).ShouldBeTrue(); @@ -626,12 +621,10 @@ var projectDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()[..4] Directory.CreateDirectory(projectDir); // Creates a local tool manifest -var exitCode = new DotNetNew("tool-manifest").WithWorkingDirectory(projectDir).Run(); -exitCode.ShouldBe(0); +new DotNetNew("tool-manifest").WithWorkingDirectory(projectDir).Run().EnsureSuccess(); // Restore local tools -exitCode = new DotNetToolRestore().WithWorkingDirectory(projectDir).Run(); -exitCode.ShouldBe(0); +new DotNetToolRestore().WithWorkingDirectory(projectDir).Run().EnsureSuccess(); ``` @@ -703,9 +696,7 @@ result.ExitCode.ShouldBe(0); using HostApi; // Shuts down all build servers that are started from dotnet. -var exitCode = new DotNetBuildServerShutdown().Run(); - -exitCode.ShouldBe(0); +new DotNetBuildServerShutdown().Run().EnsureSuccess(); ``` @@ -764,11 +755,9 @@ var dockerRun = new DockerRun() // Creates a new library project in a docker container -var exitCode = dockerRun +dockerRun .WithCommandLine(new DotNetCustom("new", "classlib", "-n", "MyLib", "--force")) - .Run(); - -exitCode.ShouldBe(0); + .Run().EnsureSuccess(); // Builds the library project in a docker container var result = dockerRun @@ -799,9 +788,8 @@ var cmd = new CommandLine("whoami"); // Runs the command line in a docker container var result = new DockerRun(cmd, "mcr.microsoft.com/dotnet/sdk") .WithAutoRemove(true) - .Run(); - -result.ShouldBe(0); + .Run() + .EnsureSuccess(); ``` diff --git a/CSharpInteractive.sln.DotSettings b/CSharpInteractive.sln.DotSettings index 76ef47e..ca8b5a9 100644 --- a/CSharpInteractive.sln.DotSettings +++ b/CSharpInteractive.sln.DotSettings @@ -305,6 +305,7 @@ True True True + True True True True diff --git a/CSharpInteractive/Core/Statistics.cs b/CSharpInteractive/Core/Statistics.cs index d89afeb..8fa895d 100644 --- a/CSharpInteractive/Core/Statistics.cs +++ b/CSharpInteractive/Core/Statistics.cs @@ -35,7 +35,6 @@ public IReadOnlyCollection Warnings } } } - public TimeSpan TimeElapsed => _stopwatch.Elapsed; diff --git a/Directory.Build.props b/Directory.Build.props index a1632c3..914e36e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,8 +12,6 @@ Copyright (C) $([System.DateTime]::Now.Year) $(Company) git https://github.com/DevTeam/csharp-interactive - true - obj/Generated False diff --git a/README.md b/README.md index d1d44a3..6a94639 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ The tool requires [.NET 6+ runtime](https://dotnet.microsoft.com/en-us/download) ## Usage +### Script runner + After installing tool you can use this tool to run C# scripts from the command line. dotnet-csi is available as a [NuGet package](https://www.nuget.org/packages/dotnet-csi/). Before installing dotnet-csi as a local tool dot not forget to create .NET local tool manifest file if it is not exist: @@ -72,7 +74,7 @@ Supported arguments: ```using HostApi;``` directive in a script allows you to use host API types without specifying the fully qualified namespace of these types. -## Debug scripts easy! +### .NET application Install the C# script template [CSharpInteractive.Templates](https://www.nuget.org/packages/CSharpInteractive.Templates) @@ -92,14 +94,12 @@ This projects contains the script *__./Build/Program.csx__*. To run this script dotnet csi Build ``` -To run this script as a console application: +To run as a .NET console application: ```shell dotnet run --project Build ``` -Open the *__./Build/Build.csproj__* in IDE and debug the script. - ## Usage Scenarios diff --git a/README_BODY.md b/README_BODY.md index ab1d46d..51e7938 100644 --- a/README_BODY.md +++ b/README_BODY.md @@ -10,6 +10,8 @@ The tool requires [.NET 6+ runtime](https://dotnet.microsoft.com/en-us/download) ## Usage +### Script runner + After installing tool you can use this tool to run C# scripts from the command line. dotnet-csi is available as a [NuGet package](https://www.nuget.org/packages/dotnet-csi/). Before installing dotnet-csi as a local tool dot not forget to create .NET local tool manifest file if it is not exist: @@ -72,7 +74,7 @@ Supported arguments: ```using HostApi;``` directive in a script allows you to use host API types without specifying the fully qualified namespace of these types. -## Debug scripts easy! +### .NET application Install the C# script template [CSharpInteractive.Templates](https://www.nuget.org/packages/CSharpInteractive.Templates) @@ -92,11 +94,9 @@ This projects contains the script *__./Build/Program.csx__*. To run this script dotnet csi Build ``` -To run this script as a console application: +To run as a .NET console application: ```shell dotnet run --project Build ``` -Open the *__./Build/Build.csproj__* in IDE and debug the script. - diff --git a/Samples/MySampleLib/Build/Program.cs b/Samples/MySampleLib/Build/Program.cs index 9bcf596..46b81f3 100644 --- a/Samples/MySampleLib/Build/Program.cs +++ b/Samples/MySampleLib/Build/Program.cs @@ -1,14 +1,73 @@ using HostApi; +using Microsoft.Extensions.DependencyInjection; +using NuGet.Versioning; + +// Output API +WriteLine("Hello"); +WriteLine("Hello !!!", Color.Highlighted); +Error("Error details", "ErrorId"); +Warning("Warning"); +Info("Some info"); +Trace("Trace message"); + +// API for arguments and parameters +Info("First argument: " + (Args.Count > 0 ? Args[0] : "empty")); +Info("Version: " + Props.Get("version", "1.0.0")); +Props["version"] = "1.0.1"; var configuration = Props.Get("configuration", "Release"); Info($"Configuration: {configuration}"); -new DotNetBuild() +// Command line API +var cmd = new CommandLine("whoami"); + +cmd.Run().EnsureSuccess(); + +// Asynchronous way +await cmd.RunAsync().EnsureSuccess(); + +// API for Docker CLI +await new DockerRun("ubuntu") + .WithCommandLine(cmd) + .WithAutoRemove(true) + .RunAsync() + .EnsureSuccess(); + +// Microsoft DI API to resolve dependencies +var nuget = GetService(); + +// Creating a custom service provider +var serviceCollection = GetService(); +serviceCollection.AddSingleton(); + +var myServiceProvider = serviceCollection.BuildServiceProvider(); +var tool = myServiceProvider.GetRequiredService(); + +// API for NuGet +var settings = new NuGetRestoreSettings("MySampleLib") + .WithVersionRange(VersionRange.Parse("[1.0.14, 1.1)")) + .WithTargetFrameworkMoniker("net6.0") + .WithPackagesPath(".packages"); + +var packages = nuget.Restore(settings); +foreach (var package in packages) +{ + Info(package.Path); +} + +// API for .NET CLI +var buildResult = new DotNetBuild() .WithConfiguration(configuration) .WithNoLogo(true) .Build() .EnsureSuccess(); +foreach (var warn in buildResult.Warnings) +{ + Info($"{warn.State} {warn.Code}: {warn.File}({warn.LineNumber}:{warn.ColumnNumber})"); +} + +// Asynchronous wayD var cts = new CancellationTokenSource(); await new DotNetTest() .WithConfiguration(configuration) @@ -21,4 +80,8 @@ // cts.Cancel(); } }, cts.Token) - .EnsureSuccess(); \ No newline at end of file + .EnsureSuccess(); + +#pragma warning disable CS9113 // Parameter is unread. +class MyTool(INuGet nuGet); +#pragma warning restore CS9113 // Parameter is unread. diff --git a/Samples/MySampleLib/MySampleLib/MySampleLib.cs b/Samples/MySampleLib/MySampleLib/MySampleLib.cs index 38f2ea4..0e3170c 100644 --- a/Samples/MySampleLib/MySampleLib/MySampleLib.cs +++ b/Samples/MySampleLib/MySampleLib/MySampleLib.cs @@ -3,6 +3,8 @@ namespace MySampleLib; public class Calculator : ICalculator { + private int _state; + public int Add(int op1, int op2) => op1 + op2; public int Sub(int op1, int op2) => op1 + op2; diff --git a/Samples/MySampleLib/MySampleLib/MySampleLib.csproj b/Samples/MySampleLib/MySampleLib/MySampleLib.csproj index 2128fca..c9d621a 100644 --- a/Samples/MySampleLib/MySampleLib/MySampleLib.csproj +++ b/Samples/MySampleLib/MySampleLib/MySampleLib.csproj @@ -3,6 +3,7 @@ net8.0;net7.0 true + false