Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: tjmoore/dotnet-version-check
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.1.0
Choose a base ref
...
head repository: tjmoore/dotnet-version-check
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 3 commits
  • 13 files changed
  • 1 contributor

Commits on Jan 15, 2020

  1. Build as single exe and target win7-x64/x86

    Drop nuget package for now
    tjmoore committed Jan 15, 2020
    Copy the full SHA
    e04d4f4 View commit details
  2. Split into two projects, one for a WinExe app and another for console…

    … EXE. The former results in a prompt for runtime when not present and the latter just reports error with a suitable error code.
    tjmoore committed Jan 15, 2020
    Copy the full SHA
    d9280db View commit details

Commits on Jan 17, 2020

  1. Update README.md

    tjmoore authored Jan 17, 2020
    Copy the full SHA
    3cfa769 View commit details
13 changes: 10 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -15,7 +15,14 @@ jobs:
with:
dotnet-version: 3.1.100

- name: Build with dotnet
run: dotnet build --configuration Release
- name: Build x64 Win app
run: dotnet publish .\WindowsWithPrompt\dotnet-version-check-win.csproj -c Release -r win7-x64


- name: Build x86 Win app
run: dotnet publish .\WindowsWithPrompt\dotnet-version-check-win.csproj -c Release -r win7-x86

- name: Build x64 console app
run: dotnet publish .\Console\dotnet-version-check-console.csproj -c Release -r win7-x64

- name: Build x86 console app
run: dotnet publish .\Console\dotnet-version-check-console.csproj -c Release -r win7-x86
35 changes: 0 additions & 35 deletions .github/workflows/publish.yml

This file was deleted.

File renamed without changes.
35 changes: 35 additions & 0 deletions Console/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Threading.Tasks;

namespace DotNetVersionCheck
{
public class Program
{
private static VersionInfo VersionInfo { get; set; } = new VersionInfo();

public static async Task<int> Main(string[] args)
{
var rootCommand = new RootCommand(description: "Reports .NET runtime version information and/or results in an error code useful to determine no runtime installed")
{
new Option(new[] { "--silent" }, "Don't write to console, just return 0 if runtime present, otherwise host will raise error code")
};

rootCommand.Handler = CommandHandler.Create<bool>(RootCommand);
await rootCommand.InvokeAsync(args);

// Normal operation returns 0. App host will return error code if there's an issue with the runtime.
return 0;
}

private static void RootCommand(bool silent)
{
if (!silent)
{
Console.WriteLine($".NET Runtime Version: {VersionInfo.RuntimeVersion}");
Console.WriteLine($".NET Target Version: {VersionInfo.TargetFramework}");
}
}
}
}
26 changes: 26 additions & 0 deletions Console/dotnet-version-check-console.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>

<!-- Target win7 x86/x64 but not self contained so is FDE, yet package as single file and compile ready-to-run for small executable -->
<RuntimeIdentifiers>win7-x64;win7-x86</RuntimeIdentifiers>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>

<Version>0.2.0</Version>

<RootNamespace>DotNetVersionCheck</RootNamespace>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\Common\VersionInfo.cs"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.CommandLine" Version="0.3.0-alpha.20054.1" />
</ItemGroup>

</Project>
45 changes: 28 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -2,38 +2,49 @@

![](https://github.com/tjmoore/dotnet-version-check/workflows/build/badge.svg)

Reports .NET runtime version information and/or triggers a prompt to install .NET Core runtime if applicable
Sample apps to simply report .NET runtime version information and can aid with an installer to check runtime presence. This simply relies on .NET Core 3 app host ability to check runtime and report error or display a prompt to download the runtime.

A use case for this is with an installer that installs a .NET Core FDD/FDE service but needs to check and install the runtime prior to starting the service, or likewise with a console or desktop app, but not wanting to wait for a prompt or error when the user launches the app itself, but install the runtime during install.

This relies on .NET Core 3+ built-in support for prompting download and install of .NET Core runtime if not installed when running an executable. This only occurs with Windows GUI Executables.
## Update

The idea is this is a simple executable that can be run during an installer, letting the .NET Core Windows executable bootstrap handle runtime version checking, download and installation. This is useful where the actual .NET Core application being installed is a console or service application which won't generate a prompt and in the case of a service cannot prompt the user without desktop interactivity.
Note: The built-in app host checks only check for the runtime required for the executable, which means for a console app it only requires the base .NET Core runtime. For a Windows app it requires .NET Core Desktop runtime and if the base runtime or hosting runtime is installed, this may still fail.

Additionally, this application can produce a window showing the runtime and target information or send that information to a console.
Not sure if different error codes returned can indicate what it missing or if using a Windows app to at least check the basic runtime is present or missing.

An alternative is to go checking install locations and/or registry as described here:
## Samples

https://github.com/dotnet/designs/blob/master/accepted/install-locations.md
There are two samples here:

However this is somewhat complicated, especially if you want to depend on a compatible install being present, e.g. same version or newer minor & patch version, so that you can pick up latest fixes. This process is built into .NET Core 3 Windows GUI executables anyway so it would seem to make sense to use that functionality.
### Console

Note, this depends on Framework Dependent Executable (FDE) mode of deployment (which is also the default for FDD now in .NET Core 3). It's not relevant to Self Contained Deploment (SCD) as the published application will contain all the dependent runtime and is fixed to the specified target runtime version and platform.
This version is simply a console app and writes version info to the console. If the runtime is not present the dotnet host will report an error with advice to the console and will return an error code, which is one of https://github.com/dotnet/runtime/blob/master/docs/design/features/host-error-codes.md

This primarily is aimed at .NET Core. It might be possible to target .NET Framework and it may report the versions, but even if that works, it likely won't prompt for install.
For example, CoreHostLibMissingFailure (0x80008083) or FrameworkMissingFailure (0x80008096) can indicate a compatible runtime required based on the target is not present. An installer could check this and then run the required installer.

The code provided here could act as an example to integrate into other applications, although the actual prompt for install functionality only really requires targetting WinExe output type.
### WindowsWithPrompt

## Usage
This version is built as a basic WPF windows app to do the same thing but shows a window with the runtime information. Perhaps useful for support scenarios.

```
dotnet-version-check:
Reports .NET runtime version information and triggers a prompt to install runtime if applicable
The key here though is when built as a WinEXE output type, the dotnet host will provide a prompt to the user to download the runtime if not present. Although currently it only directs the user's browser to the runtime download home page.


### Usage

```
Usage:
dotnet-version-check [options]
dotnet-version-check(-win|-console) [options]
Options:
--no-window Don't display window, write version information to console
--silent Don't display window or write to console. Useful to only trigger .NET Core install if necessary
--no-window Don't display window, write version information to console (Windows app only)
--silent Don't display window or write to console. Useful to only trigger .NET Core install if necessary (windows) or raise error code (windows & console)
--version Display version information
```

This relies on .NET Core 3+ built-in support for prompting download and install of .NET Core runtime if not installed when running an executable. This only occurs with Windows GUI Executables.

Note, this depends on Framework Dependent Executable (FDE) mode of deployment (which is also the default for FDD now in .NET Core 3). It's not relevant to Self Contained Deploment (SCD) as the published application will contain all the dependent runtime and is fixed to the specified target runtime version and platform.

This primarily is aimed at .NET Core. It might be possible to target .NET Framework and it may report the versions, but even if that works, it likely won't prompt for install.


File renamed without changes.
2 changes: 1 addition & 1 deletion App.xaml.cs → WindowsWithPrompt/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ public partial class App : Application

private void Application_Startup(object sender, StartupEventArgs e)
{
var rootCommand = new RootCommand(description: "Reports .NET runtime version information and triggers a prompt to install .NET Core runtime if applicable")
var rootCommand = new RootCommand(description: "Reports .NET runtime version information and/or triggers a prompt to install .NET Core runtime if applicable")
{
new Option(new[] { "--no-window" }, "Don't display window, write version information to console"),
new Option(new[] { "--silent" }, "Don't display window or write to console. Useful to only trigger .NET Core install if necessary")
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -4,15 +4,23 @@
<!-- Needs to be WinExe to trigger install prompt for .NET Core. This does prevent console output though so have to work around that -->
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>

<!-- Target win7 x86/x64 but not self contained so is FDE, yet package as single file and compile ready-to-run for small executable -->
<RuntimeIdentifiers>win7-x64;win7-x86</RuntimeIdentifiers>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>

<Version>0.2.0</Version>

<RootNamespace>DotNetVersionCheck</RootNamespace>
<UseWPF>true</UseWPF>
<PackageId>DotNetVersionCheck</PackageId>
<Version>0.1.0</Version>
<Authors>tjmoore</Authors>
<PackageDescription>Reports .NET runtime version information and/or triggers a prompt to install .NET Core runtime if applicable</PackageDescription>
<RepositoryUrl>https://github.com/tjmoore/dotnet-version-check</RepositoryUrl>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\Common\VersionInfo.cs"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.CommandLine" Version="0.3.0-alpha.20054.1" />
</ItemGroup>
16 changes: 11 additions & 5 deletions dotnet-version-check.sln
Original file line number Diff line number Diff line change
@@ -3,18 +3,24 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-version-check", "dotnet-version-check.csproj", "{56EFF347-3480-4868-B13B-C7C275940DF0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-version-check-win", "WindowsWithPrompt\dotnet-version-check-win.csproj", "{32ECB62C-D36F-4617-BCCC-E088B46CAA54}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-version-check-console", "Console\dotnet-version-check-console.csproj", "{EC1DAE36-142B-4300-97E8-A0F1907E3F0F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{56EFF347-3480-4868-B13B-C7C275940DF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56EFF347-3480-4868-B13B-C7C275940DF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56EFF347-3480-4868-B13B-C7C275940DF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56EFF347-3480-4868-B13B-C7C275940DF0}.Release|Any CPU.Build.0 = Release|Any CPU
{32ECB62C-D36F-4617-BCCC-E088B46CAA54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32ECB62C-D36F-4617-BCCC-E088B46CAA54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32ECB62C-D36F-4617-BCCC-E088B46CAA54}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32ECB62C-D36F-4617-BCCC-E088B46CAA54}.Release|Any CPU.Build.0 = Release|Any CPU
{EC1DAE36-142B-4300-97E8-A0F1907E3F0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC1DAE36-142B-4300-97E8-A0F1907E3F0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC1DAE36-142B-4300-97E8-A0F1907E3F0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC1DAE36-142B-4300-97E8-A0F1907E3F0F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE