CompilerResults CompileAssemblyFromFileBatch_with_Build(CompilerParameters options, string[] fileNames)
        {
            var projectFile = CreateProject(options, fileNames);

            var output    = "bin";
            var build_dir = projectFile.GetDirName();

            var assembly = build_dir.PathJoin(output, projectFile.GetFileNameWithoutExtension() + ".dll");

            var result = new CompilerResults();

            if (!Runtime.IsSdkInstalled())
            {
                Console.WriteLine("WARNING: .NET SDK is not installed. It is required for CS-Script to function properly.");
            }

            var config = options.IncludeDebugInformation ? "--configuration Debug" : "--configuration Release";
            var cmd    = $"build {config} -o {output} {options.CompilerOptions}";

            Profiler.get("compiler").Start();
            result.NativeCompilerReturnValue = dotnet.Run(cmd, build_dir, x => result.Output.Add(x), x => Console.WriteLine("error> " + x));
            Profiler.get("compiler").Stop();

            if (CSExecutor.options.verbose)
            {
                if (Environment.GetEnvironmentVariable("echo_compiler_cli") == null)
                {
                    var timing = result.Output.FirstOrDefault(x => x.StartsWith("Time Elapsed"));
                    if (timing != null)
                    {
                        Console.WriteLine("    dotnet: " + timing);
                    }
                }
                else
                {
                    Console.WriteLine("> ================");
                    Console.WriteLine("dotnet.exe run: ");
                    Console.WriteLine($"  current_dir: {build_dir}");
                    Console.WriteLine($"  cmd: dotnet {cmd}");
                    Console.WriteLine($"  output: {NewLine}{result.Output.JoinBy(NewLine)}");
                    Console.WriteLine("> ================");
                }
            }

            Profiler.EngineContext = "Building with dotnet engine...";

            result.ProcessErrors();

            result.Errors
            .ForEach(x =>
            {
                // by default x.FileName is a file name only
                x.FileName = fileNames.FirstOrDefault(f => f.EndsWith(x.FileName ?? "")) ?? x.FileName;
            });

            if (result.NativeCompilerReturnValue == 0 && File.Exists(assembly))
            {
                result.PathToAssembly = options.OutputAssembly;
                if (options.GenerateExecutable)
                {
                    // strangely enough on some Linux distro (e.g. WSL2) the access denied error is raised after the files are successfully copied
                    // so ignore
                    PathExtensions.FileCopy(
                        assembly.ChangeExtension(".runtimeconfig.json"),
                        result.PathToAssembly.ChangeExtension(".runtimeconfig.json"),
                        ignoreErrors: Runtime.IsLinux);

                    if (Runtime.IsLinux) // on Linux executables are without extension
                    {
                        PathExtensions.FileCopy(
                            assembly.RemoveAssemblyExtension(),
                            result.PathToAssembly.RemoveAssemblyExtension(),
                            ignoreErrors: Runtime.IsLinux);
                    }
                    else
                    {
                        PathExtensions.FileCopy(
                            assembly.ChangeExtension(".exe"),
                            result.PathToAssembly.ChangeExtension(".exe"));
                    }

                    PathExtensions.FileCopy(
                        assembly.ChangeExtension(".dll"),
                        result.PathToAssembly.ChangeExtension(".dll"),
                        ignoreErrors: Runtime.IsLinux);
                }
                else
                {
                    File.Copy(assembly, result.PathToAssembly, true);
                }

                if (options.IncludeDebugInformation)
                {
                    File.Copy(assembly.ChangeExtension(".pdb"),
                              result.PathToAssembly.ChangeExtension(".pdb"),
                              true);
                }
            }
            else
            {
                if (result.Errors.IsEmpty())
                {
                    // unknown error; e.g. invalid compiler params
                    result.Errors.Add(new CompilerError {
                        ErrorText = "Unknown compiler error"
                    });
                }
            }

            build_dir.DeleteDir(handleExceptions: true);

            return(result);
        }