Is it possible to create a standalone console application using CSharpCompilation and OutputKind.ConsoleApplication?

Wasilewski, Marek 26 Reputation points
2022-08-18T10:10:45.597+00:00

We are using the following code to create what we thought would be a standalone, .NET Core self-contained console application using CSharpCompilation. A cut down part of the code looks like this:

            // Compile the source code.  
            var csharpParseOptions = new CSharpParseOptions(LanguageVersion.Latest)  
                .WithPreprocessorSymbols(new[] { "TRACE", "DEBUG" })  
                .WithKind(SourceCodeKind.Regular);  

            var syntaxTree = CSharpSyntaxTree.ParseText(code, options: csharpParseOptions);  
            var compilationUnitSyntax = syntaxTree.GetCompilationUnitRoot();  

            var options = new CSharpCompilationOptions(OutputKind.ConsoleApplication,  
                                                       optimizationLevel: OptimizationLevel.Debug,  
                                                       platform: Platform.X64)  
                .WithModuleName("TestConsole")  
                .WithMetadataImportOptions(MetadataImportOptions.All);  

            var csharpCompilation = CSharpCompilation.Create(moduleName,  
                                                             syntaxTrees: new[] { syntaxTree },  
                                                             references: references,  
                                                             options: options);  

                    var result = csharpCompilation.Emit(fileNameOnDisk, Path.Combine(Path.GetDirectoryName(fileNameOnDisk), Path.GetFileNameWithoutExtension(fileNameOnDisk)) + ".pdb");  

                    File.WriteAllText(Path.Combine(Path.GetDirectoryName(fileNameOnDisk), $"{moduleName}.runtimeconfig.json"), "{\r\n  \"runtimeOptions\": {\r\n    \"tfm\": \"net6.0\",\r\n    \"framework\": {\r\n      \"name\": \"Microsoft.NETCore.App\",\r\n      \"version\": \"6.0.0\"\r\n    }\r\n  }\r\n}");  

The error we get at runtime is:

Unhandled Exception: System.TypeLoadException: Could not load type 'System.Object' from assembly 'System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because the parent does not exist.

The resulting exe is pretty small (35K). If we take the same code and paste it into a Visual Studio Console project and build it the resulting exe is around 145K so it looks as though the OutputKind isn't producing a self-contained console exe but one which has to be run with dotnet console.exe. We would like to know how to create a fully self-contained executable.

Thanks!

Developer technologies | .NET | .NET Runtime
Developer technologies | C#
0 comments No comments
{count} vote

Accepted answer
  1. Bruce (SqlWork.com) 77,926 Reputation points Volunteer Moderator
    2022-08-18T15:17:57.183+00:00

    Unlike classic .net, support of running .net core applications was not added to the Windows O/S. So the compiler only creates dll’s which are run with dotnet or another application.

    The early version of core just used the dotnet application and created a script file to run. Later versions of dotnet build system added support of creating a small C/C++ application to host and run the compiled .net core code.

    Building a self contained exe is another build step. How this is done is platform dependent. For MacOs (which supports application bundles) an application bundle is created. For windows it a custom C/C++ self extracting exe that extracts the files to a temp folder and runs the exe in the folder. If the temp folder exists and is current, it just runs the exe in the folder without doing the extract.

    You can run the command line dotnet program to do this build steps.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.