Skip to content

Commit

Permalink
Split into two projects, one for a WinExe app and another for console…
Browse files Browse the repository at this point in the history
… EXE. The former results in a prompt for runtime when not present and the latter just reports error with a suitable error code.
  • Loading branch information
tjmoore committed Jan 15, 2020
1 parent e04d4f4 commit d9280db
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 27 deletions.
13 changes: 9 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ jobs:
with:
dotnet-version: 3.1.100

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

- name: Build x86
run: dotnet publish -c Release -r win7-x86
- 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
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>
34 changes: 21 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,39 @@

![](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.

There are two samples here:

### Console

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

For example, CoreHostLibMissingFailure (0x80008083) can indicate a compatible runtime required based on the target is not present. An installer could check this and then run the required installer.

### WindowsWithPrompt

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.

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

```
dotnet-version-check:
Reports .NET runtime version information and/or triggers a prompt to install runtime if applicable
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.

This idea behind this is primarily for use when installing console or service applications that cannot self-prompt for install of the runtime. The solution here is by creating a WinExe executable targetting .NET Core 3 and running that during install, it should prompt for the missing runtime. This is as an alternative to scripting an installer to detect a compatible runtime globally installed which can be somewhat complex and the framework has built in support for this anyway.

The executabe need do nothing other than start and shut down, but it does have to be a WinExe target.

In this example it does a little more by providing a window showing the installed framework and/or reporting to console, but with a 'silent' option for use in an installer so it either does nothing or the user receives a prompt to install the runtime.

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.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
<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>
Expand Down
16 changes: 11 additions & 5 deletions dotnet-version-check.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d9280db

Please sign in to comment.