From a1d74c9e3f8b5c532f33fb01f30ebaf9133918e4 Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Fri, 20 Jan 2023 13:09:40 +0100 Subject: [PATCH] feat: Correctly check for Python in case of Microsoft Store --- .../WindowsPythonInstallationCheckup.cs | 89 ++++++++++++------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/UnoCheck/Checkups/WindowsPythonInstallationCheckup.cs b/UnoCheck/Checkups/WindowsPythonInstallationCheckup.cs index 6131d531..2ec41ba1 100644 --- a/UnoCheck/Checkups/WindowsPythonInstallationCheckup.cs +++ b/UnoCheck/Checkups/WindowsPythonInstallationCheckup.cs @@ -4,39 +4,66 @@ using DotNetCheck.Models; using DotNetCheck.Solutions; using Microsoft.Win32; +using System.Diagnostics; using System.Threading.Tasks; namespace DotNetCheck.Checkups { - public class WindowsPythonInstallationCheckup : Checkup - { - public override string Id => "windowspyhtonInstallation"; - - public override string Title => "Windows Python Installation Checkup"; - - public override bool IsPlatformSupported(Platform platform) => platform == Platform.Windows; - - public override async Task Examine(SharedState history) - { - RegistryKey pyLaucherKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Python\PyLauncher", false); - string? path = pyLaucherKey?.GetValue(InstallDirKey)?.ToString(); - - if (pyLaucherKey is null || string.IsNullOrEmpty(path)) - { - return await Task.FromResult(new DiagnosticResult( - Status.Error, - this, - new Suggestion("In order to build WebAssembly apps using AOT, you will need to install Python from Windows Store, or manually through Python's official site", - new PythonIsInstalledSolution()))); - } - else - { - ReportStatus($"Python is installed in {path}.", Status.Ok); - } - - return await Task.FromResult(DiagnosticResult.Ok(this)); - } - - private const string InstallDirKey = "InstallDir"; - } + public class WindowsPythonInstallationCheckup : Checkup + { + public override string Id => "windowspyhtonInstallation"; + + public override string Title => "Windows Python Installation Checkup"; + + public override bool IsPlatformSupported(Platform platform) => platform == Platform.Windows; + + public override async Task Examine(SharedState history) + { + var checkResult = RegistryCheck(); + if (!checkResult.available) + { + // In case of Microsoft Store version, the registry key is not set. + // Fall back to where command. + checkResult = WhereCheck(); + } + + if (!checkResult.available) + { + return await Task.FromResult(new DiagnosticResult( + Status.Error, + this, + new Suggestion("In order to build WebAssembly apps using AOT, you will need to install Python from Microsoft Store, winget, or manually through Python's official site", + new PythonIsInstalledSolution()))); + } + else + { + ReportStatus($"Python is installed in {checkResult.path}.", Status.Ok); + } + + return await Task.FromResult(DiagnosticResult.Ok(this)); + } + + private const string InstallDirKey = "InstallDir"; + + private (bool available, string? path) RegistryCheck() + { + var pyLaucherKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Python\PyLauncher", false); + string? path = pyLaucherKey?.GetValue(InstallDirKey)?.ToString(); + var available = pyLaucherKey is not null && !string.IsNullOrEmpty(path); + return (available, path); + } + + private (bool available, string? path) WhereCheck() + { + using Process process = new Process(); + process.StartInfo.FileName = "where"; + process.StartInfo.Arguments = "python"; + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.Start(); + + string output = process.StandardOutput.ReadToEnd(); + return (!string.IsNullOrEmpty(output), output); + } + } } \ No newline at end of file