How do I decide what runtime id to use? - .net-core

I am used to the dot net framework building a .exe file that I can release
However in .Net Core 2.0 I need to specify a runtime id when creating the .exe
for example
dotnet publish --runtime win7-x84
where the runtime id is win7
What factors should I consider when choosing the run time id?
Do I need to be releasing multiple .exe versions to cater for my clients on different operating systems?
I have looked at the document here

What factors should I consider when choosing the run time id?
Well, the main factor you should consider is a target Operating System, where the application will be launched. Everything became much simpler after .NET Core 2.0 added support of portable RIDs. Portable RIDs do not include OS details, e.g.: win-x64 or linux-x86. If operating systems belong to one platform (Windows or Linux) you could publish one version of application that will run on all OS from the family. So to build application for whole family of x64 Windows OS run the following publish command:
dotnet publish --configuration Release --runtime win-x64
Do I need to be releasing multiple .exe versions to cater for my
clients on different operating systems?
According to above explanation, there is no need in separate versions for different OS within one family. You don't need to build new versions for win7, win8, win10, etc. However you still need to publish two application versions for support of x86 and x64 architectures. It is possible to build only one x32 version that will run on both x32 and x64. However it will run in 32-bit mode on x64 OS, which should be avoided.
This question contains a lot of other details about compatibility between different RIDs and OS. Much of this outdated since portable RIDs were introduced but there is still plenty of useful info.

Related

Why Do I get PlatformNotSupportedException for System.Drawing.Common when running in a windows environment

I am developing an ASP.NET application in .NET 6. I reference ClosedXML package, which internally uses System.Drawing.Common. I understand from this explanation in Microsoft's docs that this is not supported on Linux. Developing on a windows machine this works fine. However, when I publish to a windows IIS server with this command:
dotnet publish ".\path\project.csproj" -o ".\path\bin\app.publish --runtime win-x64 --no-self-contained --configuration Release --force /p:EnvironmentName=Test
xcopy .\path\bin\app.publish \\server\c$\remote\iis\path /ydisce
...then browse to the app, calls using ClosedXML that rely on System.Drawing.Common (specifically AdjustToContents) fail with a PlatformNotSupportedException: System.Drawing.Common is not supported on this platform.
If I publish without specifying --runtime, then it works, but also includes a bunch of runtime folders I don't think it should need (ie \runtimes\unix*, win-x86, etc.). I'd like to publish just the files I need in the given environment, but also am just curious because I don't understand why I'm getting PlatformNotSupportedException in this case. It seems like System.Drawing.Common should just be checking the OS and seeing it's on windows.

What's the correct way to add references in .net core -- assembly, or nuget?

Issue:
I'm referencing the IConfiguration interface in a .net core 2.1 library that will run in a linux docker container
Visual Studio 2019 automatically offers to add an assembly reference for me. If I accept, it references the Microsoft.Extensions.Configuration.Abstractions.dll that is in my program files directory.
However, I see that there is also a nuget packager for this dll online.
It's easy to say "just trust visual studio", but I've run into issues before with the .net framework where VS (or resharper) will try to add an assembly reference when the assembly it wants to reference is really part of a package that needs to be added.
I'm a long-timer with .net, just picking up .net core. What's the correct convention in this case?
.NET Core is designed with package references as standard way to reference dependencies. There are several reasons for that design choice, however, the primary one is to allow to run code on multiple OS and arch targets. Therefore, recommended way of creating dependencies is by using package references. It will allow to fetch packages which are relevant for given OS and CPU combination.
For example, you could target with you build Windows, Linux and macOS and for Linux and Windows x64 and arm64 architectures while for macOS x64 architecture. Project referencing packages will pick for a given combination of operating system and processor architecture appropriate packages i.e. in case of SQLite it would be win-x64, win-arm64, linux-x64, linux-arm64, macOS-x64 package versions. The same is true for .NET Core packages and runtimes which would be chosen based on combination of target platform and target architecture. The general concept of handling all these combinations is abstracted by Target Framework Moniker which besides of handling OS and architecture information allows to handle version dependency information as well.
All the above is a fundamental concept for understanding versioning and OS/architecture dependency handling in .NET Core which is implemented in it's project system as well. In the case as yours you should always choose nuget package instead of assembly reference, despite suggestion made by Visual Studio which in general not always works correctly. To verify this one can check number of issues which were closed or are still open in dotent/project-system repository on github where .NET Core project system used by Visual Studio lives.
Finally, despite that referencing pure IL assemblies will work it is not future proof, since any change in the dependency which makes it platform or architecture specific (i.e. architecture specific optimizations with .NET Core HW intrinsic) would break your project.

setting up VS platfrom toolset in QtCreator

I have a project based on Qt which use QWebEngine. For compiling this project i've installed Visual Studio Express 2015 and have configured kits. My project is built, all is fine. But now i need to compile my project for Windows XP platform. I know, that for doing this it is needed to change toolset from v140 to v140_xp.
How can i set the toolset from qtcreator?
I tried to determine the difference in compiler options in both cases. For doing that I've created test project in Visual Studio. There i change the toolset and look at Project Properties -> C/C++ -> Command Line Options. But seems that nothing changes there.
Qt WebEngine module does not support Windows XP targeting, so this won't work anyway. Even if it did, you'd need to build a copy of Qt that targets Windows XP - otherwise your application will target Windows XP, but not the Qt library it uses, and it won't work that way.
For completeness sake, here's how you'd do it assuming that you got Qt built targeting Windows XP:
There only two ways to do it currently without patching Qt Creator itself:
Execute Qt Creator with environment variables already setup up for the XP toolset enabled for command line use. I.e. target XP from command line, and launch Qt Creator from there.
Add relevant environment variable settings to the Build environment of the project in Qt Creator.
The details of environment variables needed to target Windows XP are given e.g. here.
For Windows XP portability, you should be using the semi-maintained for of the qtwebkit module. It builds and works on XP, and works with most recent Qt IIRC.
Note: It's certainly possible to target XP using WebEngine and Angle, but it requires lots of patches to current Qt. It's not an insignificant effort, and you'd definitely want to test it on the graphics cards that you intend to target - the DirectX 9 drivers on some of those machines are buggy, and while the code is correct and compiles and runs, it may not work on some systems. I'd say that it's absolutely not worth the effort.
In VS there is an editbin utility, which could be used as follows
editbin file.exe /SUBSYSTEM:WINDOWS,5.01 /OSVERSION:5.1

dotnet core: When to use win10 over win7 RID?

Without specifying RuntimeIdentifiers in my csproj I got win7-x64 on both win7 and win10 machines. Both builds works (based on full framework).
I cannot find docs about - how to choose right RID and what is the difference between same-architecture-and-platform RIDs?
The.NET Core defaults to win7 for
.NET Framework projects. In most cases, win10 and win7 runtime identifiers produce identical output, especially for .NET Framework projects.
The difference only matters if you depend on a NuGet packages that has Windows 10 specific APIs, which very few do, if any. Choose the runtime identifier that matches the minimum platform you support. E.g. if you don't intend to support Windows 7, 8, or 8.1, use win10.
Or use both if you want to support multiple platforms. RuntimeIdentifiers accepts a semicolon separated list.
When you deliberately want your apps to be only used by Windows 10 users.
That can be pleasant if your apps do use Windows 10 specific features, which is not obvious for console and web apps, but might be typical when Microsoft introduces other project types such as GUI apps.
What I can think of at this moment is Windows 10 only things such as HTTP/2 support.

Compiling 32bit app on 64bit machine

I want to convert my 32bit application to 64bit so I could compile it and keep working on it on my 64bit machine. How can it be done?
To compile at 64bit:
Inside Visual Studio go to Build > Configuration Manager
Then you can specify CPU by selecting the Platform column and choosing between X86 and x64.
Then you can explicitly compile at 64bit.
That said Any CPU should be good enough for you to keep working on it. My carry around is 64bit, but the buildserver can output the projects as either 32bit or 64bit depenedent on the release template.
Also dependent on your Visual Studio version, there is the Prefer 32bit flag which may be of use dependent on your exact requirements.

Resources