I'm a newbie to Roslyn compiler services, I would like to create an .exe with .net full or .net core which can call Roslyn API, that program must run on a machine that does not have installed Visual Studio, I just want to distribute (copy/paste) the .exe and it should work.
I have no idea what programs must be installed on that machine to my .exe can work properly (making calls to Roslyn API).
Can it run only with .net framework installed?
Most of Roslyn is just a library, so if you build a project that references the Roslyn NuGet packages, it will compile into a directory of files that are all you need to run the application (assuming you have the appropriate version of .Net Framework or .Net Core installed).
If you really want just a single EXE file, you will need a tool that combines an application and its dependencies into a single file, like ILMerge.
Related
When i build my .NET Core Console Application using .NET Core 3.1 sdk,it generates both .exe as well as .dll as output. When i was using .NET Core 2.1 it was generating only .dll as output. Is there a way to restrict .NET Core 3.1 sdk to generate only .dll as output?
You can control this with the UseAppHost MSBuild setting:
The UseAppHost property was introduced in the 2.1.400 version of the .NET Core SDK. It controls whether or not a native executable is created for a deployment. A native executable is required for self-contained deployments.
In .NET Core 3.0 and later versions, a framework-dependent executable is created by default. Set the UseAppHost property to false to disable generation of the executable.
<PropertyGroup>
<UseAppHost>false</UseAppHost>
</PropertyGroup>
If you want to disable this when building from the command line, instead of setting it within the .csproj, pass the property as an argument. For example:
dotnet build /p:UseAppHost=false
In .NET, the difference between a .exe and a .dll is actually very small. .exe tend to be little more then .dll's with some bootstrap code and a start point (the class whose main method is to be called).
You can use both .NET .exe and .dll as project references. There might be some difference in some fringe details like COM interop, but I do not expect it.
What exactly the compiler will build, depends on it's inputs. Wich includes the project settings. There is a special type of project for library. And with version changes, the proper reading of projects files could be broken. And of course the option that some code is "seperated out" into a .dll is also there. Most programms nowadays are more .dll's then executeables. And it can be beneficial to keep .exe small.
In .NET framework, you can make a single .EXE file that will run from the command line without having any extra config files (and if using ILMerge, you can put all .DLL references into the 1 .EXE assembly).
I am taking a stab at using .NET Core to accomplish the same thing, but so far without success. Even the simplest Hello World application with no dependencies requires there to be a file named <MyApp>.runtimeconfig.json in order to run using dotnet.exe.
dotnet F:\temp\MyApp.dll
The contents of the <MyApp>.runtimeconfig.json are as follows:
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "1.1.1"
}
}
}
Without this config file in the same folder as the .DLL, I get the following error:
A fatal error was encountered. The library 'hostpolicy.dll' required to
execute the application was not found in 'F:\temp'.
My question is: Is there some way to change the application so it doesn't require this config file to be present, so that the defaults of this information are compiled within the .DLL but can be overridden by adding the config file?
NOTE: I also want to ensure it "just works" regardless of the platform it is installed on it provided the platform has the right version of .NET Core.
Background
I am trying to get a smooth user experience for running some utilities that are useful sometimes, but are rarely ever needed. Since it doesn't appear to be possible to use the same .DLL that is referenced from a client application as a console application, the next best thing would be to have a single file that could be downloaded and run without any dependencies.
For example, in Java you can simply download a .jar file on any supported platform and run:
java <package>.jar <namespace>.SomeClass [args]
and it will "just work" without any extra files. How can I get a similar user experience using .NET Core?
In a nutshell, I want to try to avoid the extra step of "unzip to a directory first"...
Update 2018: .NET Core 3.0 aims to enable a new scenario: packing the .NET Core runtime and all application dependencies into a single executable.
At the moment, there are no fail-safe methods to create a single executable file. Since there are a lot of type-forwarding dll files involved, even ILMerge and similar tools might not produce correct results (though this might improve, the problem is that those scenarios haven't undergone extensive testing, esp. in production applications)
There are currently two ways to deploy a .NET Core application:
As a "portable application" / "framework-dependent application", requiring a dotnet executable and installed framework on the target machine. Here, the XYZ.runtimeconfig.json is used to determine the framework version to use and also specifies runtime parameters. This deployment model allows running the same code on various platforms (windows, linux, mac)
As a "self-contained application": Here the entire runtime is included in the published output and an executable is generated (e.g. yourapp.exe). This output is specific to a platform (set via a runtime identifier) and can only be run on the targeted operating system. However, the produced executable is only a small shim that boots the runtime and loads the app's main dll file. This also allows an XYZ.runtimeconfig.json to set additional runtime properties like garbage collection settings.(think of it as a "new" app.config file)
In the future, the CoreRT runtime – which is still under development at the time of writing – aims to allow creating a single pre-compiled native executable that is specific to a runtime and does not require any other files.
Tested with .NET Core 2.2 on a console app:
Reference Microsoft.DotNet.ILCompiler package in your output project. You'll need to add MyGet package repository in Visual Studio settings. *
Publish the project via command line,
dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64. If there's no "Desktop Development for C++" component installed, do it in Visual Studio Installer, or the command will fail.
Go to the output folder (e.g. "C:\src\App\output-win-x64") and grab the native image (.exe file).
On Windows it produced a fully functional 5Mb .exe file (compared to original self-contained publish with folder size at ~60Mb). On macOS the ILComplier though produced output without any error, the app crashed with unhandled expection (on the line with LINQ expression).
*Go to "Tools -> Options -> Package Manager -> Package Sources" and add new source at https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
It is possible in .NET Core 3.0+
The feature is enabled by the usage of the following property in your project file (.csproj):
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
There are other options as well, such as packaging the pdb into the bundle, or leaving certain files out.
Documentation can be found here: https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained
True it just works:
Combine this technique with the Self Contained Deployment workflow, you can get a true "it just works" experience for your user, they don't even have to install the .NET Core runtime for your app to run.
I am currently deploying applications to my clients as single .exe files.
Read more about that here: https://learn.microsoft.com/en-us/dotnet/core/deploying/#self-contained-deployments-scd
Is there a possibility to publish .NET Core Console Application as single file (no matter if it's EXE or DLL)?
I am using .NET Core 1.1 but I am elastic to port my project to another version.
At the moment, this is not possible because:
portable applications still need at least a runtimeconfig.json to tell the host (dotnet / dotnet.exe) which shared runtime to use. Even if you IL-Merge all your managed code into a single dll, this file is still required. The host also expects a deps.json expressing the dependencies of the application.
self-contained applications rely on building a .dll + .deps.json and copying over content from runtime-specific NuGet packages. This also includes native libraries that are searched for by file name.
The CoreRT project aims to compile a .NET Core application to a single native binary using ahead-of-time compilation but is still in development.
Microsoft says it's platform neutral these days, so I'm trying to build on Mac and Linux only with VS Code and deploy to Azure. Why? It's mainly to prove that I can.
Our project has several parts which include a couple of different websites, a Web API, er API and a few other bits. On my Mac I've built a .Net Core Class Library with a load of objects in. Command line, dotnet build, DLL out, no problem.
I want to put that DLL on the Linux machine where the MVC website is being built - the objects forming the models part of that site hopefully. I cannot figure out how to get the website project to reference my DLL and use the objects.
I had assumed I copy it to the other machine, place it in the bin folder of the site being developed and reference it in the Dependencies section of the site's project.json. Nope. I saw a few articles that said .Net Core only works with NuGet and it had to be a package. Is that really true?
I've found and read (if not entirely understood) everything you could imagine on sharing between .net core and .net framework. This is a core-only project so not applicable. Frankly I'm lost, and something called .Net Standard has just rolled into my field of vision.
So instead of copying the DLL, use dotnet pack to build a nuget package on your Mac, and copy that to your Linux machine instead. Put it in a directory that you configure as a local nuget repository (no server or anything required) and you're away.
I agree it's not as straightforward as a reference to a DLL, but it's not too bad. Note that you'll need to version the package appropriately, so that the tool system can detect when it's changed.
I have been recently trying to deploy a C# application on a computer that does not have .NET installed.
I know that there have been many questions around the same topic here on StackOverflow. Here are a few of them, of which I read the responses to all:
Packaging up the .net framework with a .net application deployment
Run a .net application without installing .net client profile?
Run C# windows application in windows XP without installing .NET Framework
So all of the responses to the above questions state that it is impossible without specific software, etc. One software mentioned was the Salamander .NET Linker. The only problem with that is that I cannot seem to be able to run the application after it has been processed by Salamender. I understand that this in itself is impossible, as it requires the .NET virtual machine to run. However, in the past, I have made Java applications and along with them, I shipped the entire JVM. Surprisingly, they still worked. So the reason why this is not a duplicate of the above questions is because my true question is:
What items of the .NET framework would I need to package? If I do manage to package all, would placing them in the same directory as the application I'm running allow the application to run?
I found one solution to this, the Microsoft .NET Redist Package. The only problem with this is that it has a GUI of its own. Aside from that, it would be a perfect fit. So, could anyone tell me one of two things:
Is there a command-line .NET package, and if so, where do I download it?
If there isn't, or it would be impractical to do so, approximately what directories would I need to copy from the .NET installations?
I understand that these files and directories are system specific, and that my .NET installation may not work on your computer, but if C# is like Java, then this should be achievable. Is it? Size is not a limitation, it does not matter to me whether or not the application and all its files is 1GB, or if it is only 1MB.
If in case there is no other solution, I used Dependency Walker to check all the dependencies of my program. If I were to package most of them, would my application, in theory, work?
For .NET, you really must just install the appropriate .NET framework. The .NET framework installation does include command line options to allow for silent installs, such as:
dotnetfx35.exe /q /norestart
For details on the command line options, see the options for 3.5 and for .NET 4.0.
That being said, most installation packages will handle these details for you as part of the installation. Using a decent installer will take care of this dependency automatically.
Depending on the pieces of the .NET Framework you need, you can use Mono. It supports shipping the runtime without installing just like you would a JVM, or you can statically link against the binaries to create a native executable .
If you are planning to deploy your application (and presuming the setup process doesn't need to be too complex), you can simply create a Setup project in Visual Studio and then bootstrap the prerequisites (.NET framework, and other stuff you think you might need).
You can follow the steps described in these MSDN articles:
How to create a Setup project in Visual Studio
How to add prerequisites to a Setup project
A walkthrough is given in this CodeProject article.
For more complex deployment scenarios (such as installing device drivers along your app, or better localization support), I would recommend looking into WiX (Windows Installer XML) toolset. It's a toolset that builds Windows installation packages, which you configure using XML files inside Visual Studio. WiX also supports various bootstrapping scenarios.
This page covers the differences between VS Setup projects, WiX, and InstallShield.