What is a vNext console application? - c#

I installed Visual Studio 2015 RC to try out the ASP.Net vNext templates. In the "Web" section, I have noticed a console application that appears as
I decided I would mess around with it and I found some interesting points:
The default template does not specify Main() as static.
Many assemblies such as System.CodeDom and System.Net are not available.
Many methods such as System.Console.ReadKey cannot be used.
What are these vNext console applications? Why the restrictions and what are the uses of them?

Answers
What is a vNext console application?
It's a console application that runs within the new .NET runtime environment (DNX).
Why the restrictions and what are the uses of them?
The restrictions occur because you are targeting .NET Core (dnxcore50) instead of (or in addition to) the full .NET Framework (dnx451.) The use of those restrictions, as far as I know, is to allow cross-compatibility with a lot of different operating systems. That is, .NET Core has less functionality than the full framework does, because it is easier to be compatible with many systems that way. Overtime, those restrictions may fall away as more in made fully cross platform.
The default template does not specify Main() as static.
DNX comes with Microsoft.Framework.ApplicationHost. This default application host "knows how to find a public void Main method. This is the entry point used to set up the ASP.NET hosting layer..." It also still knows how to find the traditional static void Main method. An advantage of an instance Main method is that it lets us ask the runtime environment to inject services into our application.
Many assemblies such as System.CodeDom and System.Net are not available. Many methods such as System.Console.ReadKey cannot be used.
System.Console.ReadKey is available in dnx451 but not in dnxcore50. That's also true for System.Net the last time I checked. So, if you want to use those, make sure to target dnx451 instead of dnxcore50.
Want to remove the restrictions? Just delete the dnxcore50 entry from your project.json file. Then you'll only be targeting the full framework without restrictions.
See Also
https://msdn.microsoft.com/en-us/magazine/dn913182.aspx
'Console' does not contain a definition for 'ReadKey' in asp.net 5 console App
Using System.Net.Mail in ASP NET MVC 6 project

Those console applications are leveraging the new .NET execution environment (DNX, previously KRE). It includes a new project system and allows you to target different versions of the CLR.
One of those versions is CoreCLR which is a slim version of .NET. This version is modular and its libraries are distributed as a bunch of NuGet packages. You may need to include some additional packages when targeting .NET Core (dependencies section on your project.json file).
Nevertheless, some of the limitations may arise from the fact that not all the APIs are already migrated to .NET Core or from the fact that they won't be, since the API surface is smaller on .NET Core.

I'm slowly going through the new runtime and will update this post with relevant references.
Microsoft.Framework.Runtime.Sources.EntryPointExecutor->TryGetEntryPoint()
Has the piece of code that is picking out the Program class and its Main function

Related

Determine application framework version in library C#

I have a library which is .NET standard version. This library will be used both .NET app and .NET Core apps. I want to use IConfiguration for .NET Core apps in my library but .NET apps throw an exception.
I need to check version or determine the application if .NET Core or .NET framework? I have tried get appsettings.json file to determine app type but getting root path different both .NET and .NET Core apps.
When I tried to get framework version of app it gives me library's version.
How can I distinguish which type of application it is? How can I achieve this?
There are several ways to solve your problem:
try to use more common parameters for your methods that requires string's, int's or custom classes instead. Is it really necessary to add a framework specific class or function or is there a better option?
You can use a multi-target configuration for your library which then requires #if NET45 and #elif NETSTANDARD2_0 code everywhere you have to use different logic for different frameworks. This could lead to not very well readable code.
Use two libraries, one for .NET Core apps (e.g. based on .NET Standard 2.1) and the other for .NET Framework (e.g. .NET FW 4.8). The .cs files from the .NET Standard library can then also be used in the .NET 4.8 library (if compatible features have been used). The .cs files can be selected e.g. in VS via "context menu > add existing element". When confirming the selected file(s), expand the dropdown option under "Add" and select "Add as Link". This way the file only needs to be maintained once (changes are applied in both libraries). Framework-specific files can then be added individually in the respective library, not as a link. Here's a good article about it.
These are just some examples, there might be of course other or better solutions to it.
Personally I would try to use independent arguments for my methods, if this is not possible I prefer the custom library solution for each framework version.

Published version WPF .NET Core

I am looking to use code similar to the below, but in a .NET Core WPF C# application. This is what I previously used.
public static string GetVersion()
{
if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
{
Version myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
return $"Version {myVersion}";
}
return "Version not deployed";
}
Is there an equivalent in .NET Core?
There is a closed issue around this issue and ClickOnce deployment.
ApplicationDeployment class is not available - that class is implemented in System.Deployment assembly that is not part of .NET Core 3.1 or .NET 5.
We will have a way to expose some of the properties that the class enables, i.e. URL parameters and update status. But, that work could not be completed for .NET 5 release. We will enable it in one of .NET 6 previews. Here are the tracking issues: #27 and #53
Use of ApplicationDeployment class in your deployed ClickOnce application is not possible, but main ClickOnce experience is available. It includes: creating ClickOnce deployment (manifests), publishing the application, creating and publishing updates. Your application will get automatic update check (and update, if user accepts it) - this part is handled by ClickOnce runtime and the new Launcher tool that becomes the entry point of ClickOnce deployment for .NET Core 3.1 and .NET 5 applications.
Consequently, as for now there does not seem to be a way to do this in .NET Core directly.
You should be able to get the assembly version using System.Reflection.Assembly.GetExecutingAssembly().GetName().Version, as shown in
Reading Assembly version information of WPF application
For more click-once capabilities not ported to .net core3.1/5/6, look here https://github.com/derskythe/WpfSettings
There has been some progress on this in .NET. According to a comment by a Microsoft employee you can now detect these values via environment variables as is done in mage.exe. For example something like this:
bool.TryParse(Environment.GetEnvironmentVariable("ClickOnce_IsNetworkDeployed"), out bool isNetworkDeployed);
Version.TryParse(Environment.GetEnvironmentVariable("ClickOnce_CurrentVersion"), out Version currentVersion);
Most of the discussion on that GitHub issue is about .NET 7. On the other hand, some comments suggest this code has its own independent release schedule. I don't know enough to say if/when it will be available in Core.

Use local .NET Core system libraries instead of adding them to every package

Our client has complained about the count of .dll files in the .NET Core app we made for them. Their dissatisfaction persists even after we explained that this is how .NET Core works.
Now I do understand their position completely, my jaw dropped too when I created the package for the first time:
Note how small the scroll bar is. Most of the library names begin with Microsoft. or System. - those that don't are libraries that I use and installed manually.
So the question is: is there anything I can do about this to make our client happy? Aren't the System.* libraries already installed on their machine as a part of .NET Core runtime?
We're targeting .NET Core 1.0 at this moment.
You can create two types of deployments for .NET Core applications:
Framework-dependent deployment
Self-contained deployment
It seems you need Framework-dependent deployments (FDD).
Portable (FDD) application is similar to the traditional .NET Framework application. In this case, a certain version of the .NET Core Framework (also known as shared framework, .NET Core Runtime, redist) should be on the target computer, and when the host starts, the process will load Core CLR, Core FX from the frame folder.
Artifacts of the same Portable Application for different versions of the .NET Core platform
You can see what Directory structure of published ASP.NET Core apps should be
To run Portable applications, at least one .NET Core Runtime (shared framework) must be installed on the target machine. The framework files (s) are stored in the C:\Program Files\dotnet\shared folder.
Core is designed to do this. In old .NET Framework apps, there's a runtime dependency on .NET Framework, i.e. the end-user must have the version of the .NET Framework the application targets installed on the machine as well. Core takes a different approach; it brings everything it needs into the build. As a result, you can drop this folder on any machine, no matter how it's set up and "run" it. (Now technically, you need dotnet.exe in order to run it, unless you build as an executable, but that's just to run the main app DLL.)
Anyways, this is by design, and it's actually much better when you think about it. Your app has just the dependencies it actually needs and nothing else. You don't have to worry about external things like what version of .NET Framework is installed, etc.
That said, I know there's some third-party applications (mostly commercial) that can enable you to "bundle" DLLs or even package up everything into a single executable. However, I'm not sure how compatible, if at all, these are with .NET Core. Still, if your client insists, I'd just see if you can find some tool that does that and essentially "hide" the DLLs.

Class library references on Visual Studio 2015

I've added a new Class Library (Package) project to my solution. It's my first experience with a .NET Core (or whatever I'm using, still confused)
My class library contains two references: .NET Framework 4.5.1 and .NET Platform 5.4
I'm trying to import some code from a sample project that uses IPrincipal. For some reason it's saying that it doesn't exist on namespace "System.Security" altohugh I can get it trough intellisense.
What's wrong with my project settings?
The new feature of .NET Core and Class Library (Package) is that it targets multiple platform and will compile into multiple assemblies which get automatically packaged into a nuget package.
When your class library targets multiple targets, it will compile to all of them. So if a certain library is only available on full .NET framework but not on .NET Core or other target framework, then you may receive intellisense if your editor is set to .NET 4.5. More information can be found in my other recent answer.
You can switch back and forth with the pull down menu on top left of the coding window, show in the screenshot below.
If you do not want to target a certain framework, you have to remove it's moniker from the project.json file or use preprocessor directives to write platform specific code or libraries/replacements.
.NET Core is heavily modularized and most of only the core modules are referenced in the default project and if you need additional one you need to reference them within the dotnet5.x section.
Basically you have multiple places with "dependencies" in your project.json, a global one where you can add dependencies which are available on all targeted frameworks and one within each "frameworks" section for each of the targets only.
Though the other answer covers some basic concepts, it would require some attention on which classes are available and which are not.
Microsoft temporarily host a web site at http://packagesearch.azurewebsites.net to assist.
If you can find a suitable package for RC1 from there, then you can add it to your project.json file. If not, you will have to conditional compile it to a desktop profile or use other alternatives.

How can I deploy a C# application if users don't have .NET installed?

I have a C# program which I want to make available to my users, but the problem is that it requires .NET framework version 4.0. This is a problem because it was released pretty recently (April 2010) and a lot of people probably don't have it. To make matters worse it takes a while to download and install the framework (~10 minutes).
Is there any way I can install just a part of the framework I need? If that isn't possible can I compile my code down to a native binary for specific systems
eg. x86 32-bit, x86 64-bit, etc.
I've looked at a company called 'spoon' http://spoon.net/ but that looks like it just emulates apps on a server (sort of like citrix). What can I do to resolve this dilemma?
Anyone who wants to run your program needs the appropriate version of the .NET Framework installed. There's no way to work around this. It honestly amazes me how often this question gets asked. You can't compile .NET code down to any kind of a "native binary", and you can't distribute only the portions of the framework that you need. If all of this was important to you, you should have chosen a different development platform in the beginning.
Your only option is to bundle the .NET Framework along with your application's installer. The way to make this easiest on your customers is to use Visual Studio to create a setup project that will automatically install the .NET FW if they don't have it already, and then install your application, all in a single step process.
Visual Studio has built-in support for creating such a setup project, and most of the dirty work is handled for you. File -> New Project -> Other Project Types -> Setup & Deployment -> Visual Studio Installer. Then, pick either the "Setup Project" or "Setup Wizard" option, and follow the instructions.
The only thing to keep in mind since you've developed for .NET 4.0 is that there are two versions of this framework: the full version and the "Client Profile". The Client Profile is an attempt to do exactly as you mention and install only the portions of the framework that are used by the typical application. You have to first figure out of this is a deployment option for you. If your program uses classes that are not available in the Client Profile, you need to install the full version. Otherwise, you can consider installing the Client Profile, which is the default for all new projects targeting .NET 4.0 in VS 2010. Check the "Target Framework" settings for your application, under the project Properties. If it's not set to Client Profile already, try changing it and see if it will compile. That's the quickest way to tell if this deployment option is available to you. But there's only about a 15% difference in size between the two frameworks, so it isn't really that big of a deal if you must deploy the full version.
Either way, the setup project will automatically determine and bundle the correct version for your app. Definitely don't make the user download and run the .NET installer separately. Use the setup project and do this for them automatically. If you don't have VS or don't want to use the one it provides, investigate alternatives, like Inno Setup, which also support deploying and installing the .NET runtime with an app.
In many cases you do not need the entire .NET Framework 4.0 and can use the much smaller .NET Framework Client Profile. You can then use an installer to bundle the client profile installer with your app into a single deployment.
You cannot run a .NET app without the framework. If this is a deployment issue for your customers, you should consider either a Click-Once installer (web-based automated installation and updating) or porting the app to Silverlight.
For the sake of completeness, there is also the possibility for .NET Core release deploy Self-Contained Deployments (SCD) nowadays. When you create a self-contained deployment, .NET Core tools automatically include the latest serviced runtime of the .NET Core version that your application targets.
Deploying a Self-contained deployment has two major advantages:
You have sole control of the version of .NET Core that is deployed with your app. .NET Core can be serviced only by you.
You can be assured that the target system can run your .NET Core app, since you're providing the version of .NET Core that it will run on.
Here is a small guide from Scott Hanselman.

Categories