From bbaa87168b0277b23a3c74fc475874295b09099c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 09:25:45 +0000 Subject: [PATCH 01/10] Add .NET 8 Desktop Runtime check to installers This change adds a check to the Inno Setup installers to ensure that the .NET 8 Desktop Runtime is installed before allowing the installation to proceed. If the runtime is not found, a message is displayed to the user with a link to the download page, and the installation is aborted. This addresses the issue where the installer would fail silently if the .NET runtime was not present. This change modifies the following installer scripts: - `release/pyrevit.iss` - `release/pyrevit-cli.iss` - `release/pyrevit-admin.iss` --- release/pyrevit-admin.iss | 76 ++++++++++++++++++++++++++++++++++++++ release/pyrevit-cli.iss | 78 ++++++++++++++++++++++++++++++++++++++- release/pyrevit.iss | 76 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+), 1 deletion(-) diff --git a/release/pyrevit-admin.iss b/release/pyrevit-admin.iss index 3e6590c89d..affd834489 100644 --- a/release/pyrevit-admin.iss +++ b/release/pyrevit-admin.iss @@ -85,3 +85,79 @@ Filename: "{app}\bin\pyrevit.exe"; Description: "Attaching this clone..."; Param [UninstallRun] Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches clear --all"; Flags: runhidden runascurrentuser Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden runascurrentuser + +[Code] +const + REQUIRED_MAJOR_VERSION = 8; + DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; + +function GetDotNetDesktopRuntimeVersion(var Major, Minor, Patch: Integer): Boolean; +var + Path: String; + FindRec: TFindRec; + Version, MajorStr, MinorStr, PatchStr: String; + SeparatorPos: Integer; +begin + Result := False; + Path := ExpandConstant('{autopf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); + if not DirExists(Path) then + begin + Path := ExpandConstant('{autopf}\dotnet\shared\Microsoft.WindowsDesktop.App'); + if not DirExists(Path) then + Exit; + end; + + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then + begin + Version := FindRec.Name; + SeparatorPos := Pos('.', Version); + if SeparatorPos > 0 then + begin + MajorStr := Copy(Version, 1, SeparatorPos - 1); + Delete(Version, 1, SeparatorPos); + SeparatorPos := Pos('.', Version); + if SeparatorPos > 0 then + begin + MinorStr := Copy(Version, 1, SeparatorPos - 1); + PatchStr := Copy(Version, SeparatorPos + 1, Length(Version)); + Major := StrToInt(MajorStr); + Minor := StrToInt(MinorStr); + Patch := StrToInt(PatchStr); + if Major > REQUIRED_MAJOR_VERSION then + begin + Result := True; + Exit; + end + else if Major = REQUIRED_MAJOR_VERSION then + begin + Result := True; + end; + end; + end; + end; + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; + end; +end; + +function InitializeSetup(): Boolean; +var + Major, Minor, Patch: Integer; +begin + if GetDotNetDesktopRuntimeVersion(Major, Minor, Patch) then + begin + Result := True; + end + else + begin + MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); + ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); + Result := False; + end; +end; diff --git a/release/pyrevit-cli.iss b/release/pyrevit-cli.iss index b703bbffc2..68c7544a18 100644 --- a/release/pyrevit-cli.iss +++ b/release/pyrevit-cli.iss @@ -60,4 +60,80 @@ Filename: "{app}\bin\pyrevit.exe"; Description: "Detach existing clones..."; Par [UninstallRun] Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches clear --all"; Flags: runhidden -Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden \ No newline at end of file +Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden + +[Code] +const + REQUIRED_MAJOR_VERSION = 8; + DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; + +function GetDotNetDesktopRuntimeVersion(var Major, Minor, Patch: Integer): Boolean; +var + Path: String; + FindRec: TFindRec; + Version, MajorStr, MinorStr, PatchStr: String; + SeparatorPos: Integer; +begin + Result := False; + Path := ExpandConstant('{autopf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); + if not DirExists(Path) then + begin + Path := ExpandConstant('{autopf}\dotnet\shared\Microsoft.WindowsDesktop.App'); + if not DirExists(Path) then + Exit; + end; + + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then + begin + Version := FindRec.Name; + SeparatorPos := Pos('.', Version); + if SeparatorPos > 0 then + begin + MajorStr := Copy(Version, 1, SeparatorPos - 1); + Delete(Version, 1, SeparatorPos); + SeparatorPos := Pos('.', Version); + if SeparatorPos > 0 then + begin + MinorStr := Copy(Version, 1, SeparatorPos - 1); + PatchStr := Copy(Version, SeparatorPos + 1, Length(Version)); + Major := StrToInt(MajorStr); + Minor := StrToInt(MinorStr); + Patch := StrToInt(PatchStr); + if Major > REQUIRED_MAJOR_VERSION then + begin + Result := True; + Exit; + end + else if Major = REQUIRED_MAJOR_VERSION then + begin + Result := True; + end; + end; + end; + end; + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; + end; +end; + +function InitializeSetup(): Boolean; +var + Major, Minor, Patch: Integer; +begin + if GetDotNetDesktopRuntimeVersion(Major, Minor, Patch) then + begin + Result := True; + end + else + begin + MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); + ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); + Result := False; + end; +end; \ No newline at end of file diff --git a/release/pyrevit.iss b/release/pyrevit.iss index e8ddf04b62..82beab035e 100644 --- a/release/pyrevit.iss +++ b/release/pyrevit.iss @@ -85,3 +85,79 @@ Filename: "{app}\bin\pyrevit.exe"; Description: "Attaching this clone..."; Param [UninstallRun] Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches clear --all"; Flags: runhidden Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden + +[Code] +const + REQUIRED_MAJOR_VERSION = 8; + DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; + +function GetDotNetDesktopRuntimeVersion(var Major, Minor, Patch: Integer): Boolean; +var + Path: String; + FindRec: TFindRec; + Version, MajorStr, MinorStr, PatchStr: String; + SeparatorPos: Integer; +begin + Result := False; + Path := ExpandConstant('{autopf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); + if not DirExists(Path) then + begin + Path := ExpandConstant('{autopf}\dotnet\shared\Microsoft.WindowsDesktop.App'); + if not DirExists(Path) then + Exit; + end; + + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then + begin + Version := FindRec.Name; + SeparatorPos := Pos('.', Version); + if SeparatorPos > 0 then + begin + MajorStr := Copy(Version, 1, SeparatorPos - 1); + Delete(Version, 1, SeparatorPos); + SeparatorPos := Pos('.', Version); + if SeparatorPos > 0 then + begin + MinorStr := Copy(Version, 1, SeparatorPos - 1); + PatchStr := Copy(Version, SeparatorPos + 1, Length(Version)); + Major := StrToInt(MajorStr); + Minor := StrToInt(MinorStr); + Patch := StrToInt(PatchStr); + if Major > REQUIRED_MAJOR_VERSION then + begin + Result := True; + Exit; + end + else if Major = REQUIRED_MAJOR_VERSION then + begin + Result := True; + end; + end; + end; + end; + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; + end; +end; + +function InitializeSetup(): Boolean; +var + Major, Minor, Patch: Integer; +begin + if GetDotNetDesktopRuntimeVersion(Major, Minor, Patch) then + begin + Result := True; + end + else + begin + MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); + ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); + Result := False; + end; +end; From 86e5f012ba6ba6a53dda56733762713cc82e245c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 11:14:05 +0000 Subject: [PATCH 02/10] feat: Add .NET 8 Desktop Runtime check to installers This commit introduces a prerequisite check to the Inno Setup installers for pyRevit. The check verifies that the .NET 8 Desktop Runtime (or a later version) is installed on the system before allowing the installation to proceed. If the required runtime is not found, the installer will: 1. Display an informative message to the user. 2. Provide a link to the official .NET 8 download page. 3. Abort the installation process. This prevents the silent failure reported in the issue and provides a clear, actionable path for the user. The check has been added to the following installer scripts: - `release/pyrevit.iss` - `release/pyrevit-cli.iss` - `release/pyrevit-admin.iss` --- release/pyrevit-admin.iss | 86 +++++++++++++++++++++------------------ release/pyrevit-cli.iss | 86 +++++++++++++++++++++------------------ release/pyrevit.iss | 86 +++++++++++++++++++++------------------ 3 files changed, 138 insertions(+), 120 deletions(-) diff --git a/release/pyrevit-admin.iss b/release/pyrevit-admin.iss index affd834489..c159091230 100644 --- a/release/pyrevit-admin.iss +++ b/release/pyrevit-admin.iss @@ -91,66 +91,72 @@ const REQUIRED_MAJOR_VERSION = 8; DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; -function GetDotNetDesktopRuntimeVersion(var Major, Minor, Patch: Integer): Boolean; +function CheckForDotNetRuntime(Path: String): Boolean; var - Path: String; FindRec: TFindRec; - Version, MajorStr, MinorStr, PatchStr: String; + Version: String; + Major: Integer; SeparatorPos: Integer; begin Result := False; - Path := ExpandConstant('{autopf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if not DirExists(Path) then + if DirExists(Path) then begin - Path := ExpandConstant('{autopf}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if not DirExists(Path) then - Exit; - end; - - if FindFirst(Path + '\*', FindRec) then - begin - try - repeat - if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then - begin - Version := FindRec.Name; - SeparatorPos := Pos('.', Version); - if SeparatorPos > 0 then + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin - MajorStr := Copy(Version, 1, SeparatorPos - 1); - Delete(Version, 1, SeparatorPos); + Version := FindRec.Name; SeparatorPos := Pos('.', Version); if SeparatorPos > 0 then begin - MinorStr := Copy(Version, 1, SeparatorPos - 1); - PatchStr := Copy(Version, SeparatorPos + 1, Length(Version)); - Major := StrToInt(MajorStr); - Minor := StrToInt(MinorStr); - Patch := StrToInt(PatchStr); - if Major > REQUIRED_MAJOR_VERSION then - begin - Result := True; - Exit; - end - else if Major = REQUIRED_MAJOR_VERSION then - begin - Result := True; + try + Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); + if Major >= REQUIRED_MAJOR_VERSION then + begin + Result := True; + Exit; + end; + except end; end; end; - end; - until not FindNext(FindRec); - finally - FindClose(FindRec); + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; end; end; end; +function IsDotNetDesktopRuntimeInstalled(): Boolean; +var + PathX64, PathX86: String; +begin + PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); + PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); + + if CheckForDotNetRuntime(PathX64) then + begin + Result := True; + Exit; + end; + + if CheckForDotNetRuntime(PathX86) then + begin + Result := True; + Exit; + end; + + Result := False; +end; + function InitializeSetup(): Boolean; var - Major, Minor, Patch: Integer; + ErrorCode: Integer; begin - if GetDotNetDesktopRuntimeVersion(Major, Minor, Patch) then + if IsDotNetDesktopRuntimeInstalled() then begin Result := True; end diff --git a/release/pyrevit-cli.iss b/release/pyrevit-cli.iss index 68c7544a18..4a07c1507c 100644 --- a/release/pyrevit-cli.iss +++ b/release/pyrevit-cli.iss @@ -67,66 +67,72 @@ const REQUIRED_MAJOR_VERSION = 8; DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; -function GetDotNetDesktopRuntimeVersion(var Major, Minor, Patch: Integer): Boolean; +function CheckForDotNetRuntime(Path: String): Boolean; var - Path: String; FindRec: TFindRec; - Version, MajorStr, MinorStr, PatchStr: String; + Version: String; + Major: Integer; SeparatorPos: Integer; begin Result := False; - Path := ExpandConstant('{autopf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if not DirExists(Path) then + if DirExists(Path) then begin - Path := ExpandConstant('{autopf}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if not DirExists(Path) then - Exit; - end; - - if FindFirst(Path + '\*', FindRec) then - begin - try - repeat - if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then - begin - Version := FindRec.Name; - SeparatorPos := Pos('.', Version); - if SeparatorPos > 0 then + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin - MajorStr := Copy(Version, 1, SeparatorPos - 1); - Delete(Version, 1, SeparatorPos); + Version := FindRec.Name; SeparatorPos := Pos('.', Version); if SeparatorPos > 0 then begin - MinorStr := Copy(Version, 1, SeparatorPos - 1); - PatchStr := Copy(Version, SeparatorPos + 1, Length(Version)); - Major := StrToInt(MajorStr); - Minor := StrToInt(MinorStr); - Patch := StrToInt(PatchStr); - if Major > REQUIRED_MAJOR_VERSION then - begin - Result := True; - Exit; - end - else if Major = REQUIRED_MAJOR_VERSION then - begin - Result := True; + try + Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); + if Major >= REQUIRED_MAJOR_VERSION then + begin + Result := True; + Exit; + end; + except end; end; end; - end; - until not FindNext(FindRec); - finally - FindClose(FindRec); + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; end; end; end; +function IsDotNetDesktopRuntimeInstalled(): Boolean; +var + PathX64, PathX86: String; +begin + PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); + PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); + + if CheckForDotNetRuntime(PathX64) then + begin + Result := True; + Exit; + end; + + if CheckForDotNetRuntime(PathX86) then + begin + Result := True; + Exit; + end; + + Result := False; +end; + function InitializeSetup(): Boolean; var - Major, Minor, Patch: Integer; + ErrorCode: Integer; begin - if GetDotNetDesktopRuntimeVersion(Major, Minor, Patch) then + if IsDotNetDesktopRuntimeInstalled() then begin Result := True; end diff --git a/release/pyrevit.iss b/release/pyrevit.iss index 82beab035e..42362d9132 100644 --- a/release/pyrevit.iss +++ b/release/pyrevit.iss @@ -91,66 +91,72 @@ const REQUIRED_MAJOR_VERSION = 8; DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; -function GetDotNetDesktopRuntimeVersion(var Major, Minor, Patch: Integer): Boolean; +function CheckForDotNetRuntime(Path: String): Boolean; var - Path: String; FindRec: TFindRec; - Version, MajorStr, MinorStr, PatchStr: String; + Version: String; + Major: Integer; SeparatorPos: Integer; begin Result := False; - Path := ExpandConstant('{autopf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if not DirExists(Path) then + if DirExists(Path) then begin - Path := ExpandConstant('{autopf}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if not DirExists(Path) then - Exit; - end; - - if FindFirst(Path + '\*', FindRec) then - begin - try - repeat - if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then - begin - Version := FindRec.Name; - SeparatorPos := Pos('.', Version); - if SeparatorPos > 0 then + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin - MajorStr := Copy(Version, 1, SeparatorPos - 1); - Delete(Version, 1, SeparatorPos); + Version := FindRec.Name; SeparatorPos := Pos('.', Version); if SeparatorPos > 0 then begin - MinorStr := Copy(Version, 1, SeparatorPos - 1); - PatchStr := Copy(Version, SeparatorPos + 1, Length(Version)); - Major := StrToInt(MajorStr); - Minor := StrToInt(MinorStr); - Patch := StrToInt(PatchStr); - if Major > REQUIRED_MAJOR_VERSION then - begin - Result := True; - Exit; - end - else if Major = REQUIRED_MAJOR_VERSION then - begin - Result := True; + try + Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); + if Major >= REQUIRED_MAJOR_VERSION then + begin + Result := True; + Exit; + end; + except end; end; end; - end; - until not FindNext(FindRec); - finally - FindClose(FindRec); + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; end; end; end; +function IsDotNetDesktopRuntimeInstalled(): Boolean; +var + PathX64, PathX86: String; +begin + PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); + PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); + + if CheckForDotNetRuntime(PathX64) then + begin + Result := True; + Exit; + end; + + if CheckForDotNetRuntime(PathX86) then + begin + Result := True; + Exit; + end; + + Result := False; +end; + function InitializeSetup(): Boolean; var - Major, Minor, Patch: Integer; + ErrorCode: Integer; begin - if GetDotNetDesktopRuntimeVersion(Major, Minor, Patch) then + if IsDotNetDesktopRuntimeInstalled() then begin Result := True; end From 12661b04bd0df5b2a683a3803ac44da3565dd1f3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:22:26 +0000 Subject: [PATCH 03/10] fix: Add .NET 8 Desktop Runtime check to installers This commit introduces a prerequisite check to the Inno Setup installers for pyRevit. The check verifies that the .NET 8 Desktop Runtime (or a later version) is installed on the system before allowing the installation to proceed. This is accomplished by adding a `[Code]` section to the installer scripts that uses the `InitializeWizard` event function. This function is called after the installer UI is initialized, allowing for a message box to be displayed reliably. If the required runtime is not found, the installer will: 1. Display an informative message to the user. 2. Provide a link to the official .NET 8 download page. 3. Abort the installation process. This prevents the silent failure reported in the issue and provides a clear, actionable path for the user. The check has been added to the following installer scripts: - `release/pyrevit.iss` - `release/pyrevit-cli.iss` - `release/pyrevit-admin.iss` --- release/pyrevit-admin.iss | 10 +++------- release/pyrevit-cli.iss | 10 +++------- release/pyrevit.iss | 10 +++------- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/release/pyrevit-admin.iss b/release/pyrevit-admin.iss index c159091230..a381e9e39b 100644 --- a/release/pyrevit-admin.iss +++ b/release/pyrevit-admin.iss @@ -152,18 +152,14 @@ begin Result := False; end; -function InitializeSetup(): Boolean; +procedure InitializeWizard(); var ErrorCode: Integer; begin - if IsDotNetDesktopRuntimeInstalled() then - begin - Result := True; - end - else + if not IsDotNetDesktopRuntimeInstalled() then begin MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Result := False; + Abort; end; end; diff --git a/release/pyrevit-cli.iss b/release/pyrevit-cli.iss index 4a07c1507c..6454097bbc 100644 --- a/release/pyrevit-cli.iss +++ b/release/pyrevit-cli.iss @@ -128,18 +128,14 @@ begin Result := False; end; -function InitializeSetup(): Boolean; +procedure InitializeWizard(); var ErrorCode: Integer; begin - if IsDotNetDesktopRuntimeInstalled() then - begin - Result := True; - end - else + if not IsDotNetDesktopRuntimeInstalled() then begin MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Result := False; + Abort; end; end; \ No newline at end of file diff --git a/release/pyrevit.iss b/release/pyrevit.iss index 42362d9132..4e76c8c63b 100644 --- a/release/pyrevit.iss +++ b/release/pyrevit.iss @@ -152,18 +152,14 @@ begin Result := False; end; -function InitializeSetup(): Boolean; +procedure InitializeWizard(); var ErrorCode: Integer; begin - if IsDotNetDesktopRuntimeInstalled() then - begin - Result := True; - end - else + if not IsDotNetDesktopRuntimeInstalled() then begin MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Result := False; + Abort; end; end; From 3efd618a588b98f05e7173e135c20a840963b539 Mon Sep 17 00:00:00 2001 From: Jean-Marc Couffin Date: Tue, 19 Aug 2025 18:01:31 +0200 Subject: [PATCH 04/10] Update pyrevit-cli.iss --- release/pyrevit-cli.iss | 76 ++--------------------------------------- 1 file changed, 2 insertions(+), 74 deletions(-) diff --git a/release/pyrevit-cli.iss b/release/pyrevit-cli.iss index 440b0dd17d..0eb35b04bd 100644 --- a/release/pyrevit-cli.iss +++ b/release/pyrevit-cli.iss @@ -63,79 +63,7 @@ Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden [Code] -const - REQUIRED_MAJOR_VERSION = 8; - DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; - -function CheckForDotNetRuntime(Path: String): Boolean; -var - FindRec: TFindRec; - Version: String; - Major: Integer; - SeparatorPos: Integer; -begin - Result := False; - if DirExists(Path) then - begin - if FindFirst(Path + '\*', FindRec) then - begin - try - repeat - if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then - begin - Version := FindRec.Name; - SeparatorPos := Pos('.', Version); - if SeparatorPos > 0 then - begin - try - Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); - if Major >= REQUIRED_MAJOR_VERSION then - begin - Result := True; - Exit; - end; - except - end; - end; - end; - until not FindNext(FindRec); - finally - FindClose(FindRec); - end; - end; - end; -end; - -function IsDotNetDesktopRuntimeInstalled(): Boolean; -var - PathX64, PathX86: String; -begin - PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); - PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); - - if CheckForDotNetRuntime(PathX64) then - begin - Result := True; - Exit; - end; - - if CheckForDotNetRuntime(PathX86) then - begin - Result := True; - Exit; - end; - - Result := False; -end; - procedure InitializeWizard(); -var - ErrorCode: Integer; begin - if not IsDotNetDesktopRuntimeInstalled() then - begin - MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); - ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Abort; - end; -end; \ No newline at end of file + MsgBox('Hello from pyRevit installer!', mbInformation, MB_OK); +end; From 862cc15194907526c939cb435d416f9a17079926 Mon Sep 17 00:00:00 2001 From: Jean-Marc Couffin Date: Tue, 19 Aug 2025 18:01:58 +0200 Subject: [PATCH 05/10] Update pyrevit-cli-admin.iss --- release/pyrevit-cli-admin.iss | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/release/pyrevit-cli-admin.iss b/release/pyrevit-cli-admin.iss index df6ac2f564..190c28d2bb 100644 --- a/release/pyrevit-cli-admin.iss +++ b/release/pyrevit-cli-admin.iss @@ -60,4 +60,10 @@ Filename: "{app}\bin\pyrevit.exe"; Description: "Detach existing clones..."; Par [UninstallRun] Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches clear --all"; Flags: runhidden runascurrentuser -Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden runascurrentuser \ No newline at end of file +Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden runascurrentuser + +[Code] +procedure InitializeWizard(); +begin + MsgBox('Hello from pyRevit installer!', mbInformation, MB_OK); +end; From f491ac9c329b97dd8efd9eb9c549419c679b77b9 Mon Sep 17 00:00:00 2001 From: Jean-Marc Couffin Date: Tue, 19 Aug 2025 18:02:39 +0200 Subject: [PATCH 06/10] Update pyrevit.iss --- release/pyrevit.iss | 74 +-------------------------------------------- 1 file changed, 1 insertion(+), 73 deletions(-) diff --git a/release/pyrevit.iss b/release/pyrevit.iss index 960efa5067..1b2875a1c1 100644 --- a/release/pyrevit.iss +++ b/release/pyrevit.iss @@ -87,79 +87,7 @@ Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden [Code] -const - REQUIRED_MAJOR_VERSION = 8; - DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; - -function CheckForDotNetRuntime(Path: String): Boolean; -var - FindRec: TFindRec; - Version: String; - Major: Integer; - SeparatorPos: Integer; -begin - Result := False; - if DirExists(Path) then - begin - if FindFirst(Path + '\*', FindRec) then - begin - try - repeat - if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then - begin - Version := FindRec.Name; - SeparatorPos := Pos('.', Version); - if SeparatorPos > 0 then - begin - try - Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); - if Major >= REQUIRED_MAJOR_VERSION then - begin - Result := True; - Exit; - end; - except - end; - end; - end; - until not FindNext(FindRec); - finally - FindClose(FindRec); - end; - end; - end; -end; - -function IsDotNetDesktopRuntimeInstalled(): Boolean; -var - PathX64, PathX86: String; -begin - PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); - PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); - - if CheckForDotNetRuntime(PathX64) then - begin - Result := True; - Exit; - end; - - if CheckForDotNetRuntime(PathX86) then - begin - Result := True; - Exit; - end; - - Result := False; -end; - procedure InitializeWizard(); -var - ErrorCode: Integer; begin - if not IsDotNetDesktopRuntimeInstalled() then - begin - MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); - ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Abort; - end; + MsgBox('Hello from pyRevit installer!', mbInformation, MB_OK); end; From e9602ddb997f204d8316e0bb80ed545177e257fd Mon Sep 17 00:00:00 2001 From: Jean-Marc Couffin Date: Tue, 19 Aug 2025 18:03:09 +0200 Subject: [PATCH 07/10] Update pyrevit-admin.iss --- release/pyrevit-admin.iss | 74 +-------------------------------------- 1 file changed, 1 insertion(+), 73 deletions(-) diff --git a/release/pyrevit-admin.iss b/release/pyrevit-admin.iss index faabc55266..f19d7d6417 100644 --- a/release/pyrevit-admin.iss +++ b/release/pyrevit-admin.iss @@ -87,79 +87,7 @@ Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden runascurrentuser [Code] -const - REQUIRED_MAJOR_VERSION = 8; - DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; - -function CheckForDotNetRuntime(Path: String): Boolean; -var - FindRec: TFindRec; - Version: String; - Major: Integer; - SeparatorPos: Integer; -begin - Result := False; - if DirExists(Path) then - begin - if FindFirst(Path + '\*', FindRec) then - begin - try - repeat - if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then - begin - Version := FindRec.Name; - SeparatorPos := Pos('.', Version); - if SeparatorPos > 0 then - begin - try - Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); - if Major >= REQUIRED_MAJOR_VERSION then - begin - Result := True; - Exit; - end; - except - end; - end; - end; - until not FindNext(FindRec); - finally - FindClose(FindRec); - end; - end; - end; -end; - -function IsDotNetDesktopRuntimeInstalled(): Boolean; -var - PathX64, PathX86: String; -begin - PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); - PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); - - if CheckForDotNetRuntime(PathX64) then - begin - Result := True; - Exit; - end; - - if CheckForDotNetRuntime(PathX86) then - begin - Result := True; - Exit; - end; - - Result := False; -end; - procedure InitializeWizard(); -var - ErrorCode: Integer; begin - if not IsDotNetDesktopRuntimeInstalled() then - begin - MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); - ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Abort; - end; + MsgBox('Hello from pyRevit installer!', mbInformation, MB_OK); end; From 408f3feac47f9bca0e85498c22dbe01fdfd236bd Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 16:59:44 +0000 Subject: [PATCH 08/10] test: Add diagnostic check for .NET runtime to installers This commit adds a diagnostic script to the Inno Setup installers. The script checks for the existence of the .NET 8 Desktop Runtime and displays its findings in a message box. This is a diagnostic step to confirm that the runtime detection logic is working correctly in the user's environment before implementing the final abort logic. The script has been added to the following installer files: - `release/pyrevit.iss` - `release/pyrevit-cli.iss` - `release/pyrevit-admin.iss` - `release/pyrevit-cli-admin.iss` --- release/pyrevit-admin.iss | 36 ++++++++------- release/pyrevit-cli-admin.iss | 84 ++++++++++++++++++++++++++++++++++- release/pyrevit-cli.iss | 36 ++++++++------- release/pyrevit.iss | 36 ++++++++------- 4 files changed, 143 insertions(+), 49 deletions(-) diff --git a/release/pyrevit-admin.iss b/release/pyrevit-admin.iss index a381e9e39b..c95d692796 100644 --- a/release/pyrevit-admin.iss +++ b/release/pyrevit-admin.iss @@ -89,9 +89,8 @@ Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detac [Code] const REQUIRED_MAJOR_VERSION = 8; - DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; -function CheckForDotNetRuntime(Path: String): Boolean; +function CheckForDotNetRuntime(Path: String; var FoundVersion: String): Boolean; var FindRec: TFindRec; Version: String; @@ -115,6 +114,7 @@ begin Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); if Major >= REQUIRED_MAJOR_VERSION then begin + FoundVersion := Version; Result := True; Exit; end; @@ -130,36 +130,40 @@ begin end; end; -function IsDotNetDesktopRuntimeInstalled(): Boolean; +procedure GetDotNetDesktopRuntimeInfo(var Found: Boolean; var Version: String; var Path: String); var PathX64, PathX86: String; begin PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if CheckForDotNetRuntime(PathX64) then + Found := CheckForDotNetRuntime(PathX64, Version); + if Found then begin - Result := True; - Exit; + Path := PathX64; + Exit; end; - if CheckForDotNetRuntime(PathX86) then + Found := CheckForDotNetRuntime(PathX86, Version); + if Found then begin - Result := True; - Exit; + Path := PathX86; + Exit; end; - - Result := False; end; procedure InitializeWizard(); var - ErrorCode: Integer; + IsInstalled: Boolean; + FoundVersion, FoundPath: String; begin - if not IsDotNetDesktopRuntimeInstalled() then + GetDotNetDesktopRuntimeInfo(IsInstalled, FoundVersion, FoundPath); + if IsInstalled then + begin + MsgBox('Found compatible .NET Desktop Runtime.'#13#10#13#10'Version: ' + FoundVersion + #13#10'Path: ' + FoundPath, mbInformation, MB_OK); + end + else begin - MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); - ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Abort; + MsgBox('Could not find .NET 8 Desktop Runtime.', mbError, MB_OK); end; end; diff --git a/release/pyrevit-cli-admin.iss b/release/pyrevit-cli-admin.iss index c0907674ad..4a5add80c0 100644 --- a/release/pyrevit-cli-admin.iss +++ b/release/pyrevit-cli-admin.iss @@ -60,4 +60,86 @@ Filename: "{app}\bin\pyrevit.exe"; Description: "Detach existing clones..."; Par [UninstallRun] Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "ClearCaches"; Parameters: "caches clear --all"; Flags: runhidden runascurrentuser -Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden runascurrentuser \ No newline at end of file +Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detach --all"; Flags: runhidden runascurrentuser + +[Code] +const + REQUIRED_MAJOR_VERSION = 8; + +function CheckForDotNetRuntime(Path: String; var FoundVersion: String): Boolean; +var + FindRec: TFindRec; + Version: String; + Major: Integer; + SeparatorPos: Integer; +begin + Result := False; + if DirExists(Path) then + begin + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and (FindRec.Name <> '.') and (FindRec.Name <> '..') then + begin + Version := FindRec.Name; + SeparatorPos := Pos('.', Version); + if SeparatorPos > 0 then + begin + try + Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); + if Major >= REQUIRED_MAJOR_VERSION then + begin + FoundVersion := Version; + Result := True; + Exit; + end; + except + end; + end; + end; + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; + end; + end; +end; + +procedure GetDotNetDesktopRuntimeInfo(var Found: Boolean; var Version: String; var Path: String); +var + PathX64, PathX86: String; +begin + PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); + PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); + + Found := CheckForDotNetRuntime(PathX64, Version); + if Found then + begin + Path := PathX64; + Exit; + end; + + Found := CheckForDotNetRuntime(PathX86, Version); + if Found then + begin + Path := PathX86; + Exit; + end; +end; + +procedure InitializeWizard(); +var + IsInstalled: Boolean; + FoundVersion, FoundPath: String; +begin + GetDotNetDesktopRuntimeInfo(IsInstalled, FoundVersion, FoundPath); + if IsInstalled then + begin + MsgBox('Found compatible .NET Desktop Runtime.'#13#10#13#10'Version: ' + FoundVersion + #13#10'Path: ' + FoundPath, mbInformation, MB_OK); + end + else + begin + MsgBox('Could not find .NET 8 Desktop Runtime.', mbError, MB_OK); + end; +end; \ No newline at end of file diff --git a/release/pyrevit-cli.iss b/release/pyrevit-cli.iss index 6454097bbc..3c43d58929 100644 --- a/release/pyrevit-cli.iss +++ b/release/pyrevit-cli.iss @@ -65,9 +65,8 @@ Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detac [Code] const REQUIRED_MAJOR_VERSION = 8; - DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; -function CheckForDotNetRuntime(Path: String): Boolean; +function CheckForDotNetRuntime(Path: String; var FoundVersion: String): Boolean; var FindRec: TFindRec; Version: String; @@ -91,6 +90,7 @@ begin Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); if Major >= REQUIRED_MAJOR_VERSION then begin + FoundVersion := Version; Result := True; Exit; end; @@ -106,36 +106,40 @@ begin end; end; -function IsDotNetDesktopRuntimeInstalled(): Boolean; +procedure GetDotNetDesktopRuntimeInfo(var Found: Boolean; var Version: String; var Path: String); var PathX64, PathX86: String; begin PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if CheckForDotNetRuntime(PathX64) then + Found := CheckForDotNetRuntime(PathX64, Version); + if Found then begin - Result := True; - Exit; + Path := PathX64; + Exit; end; - if CheckForDotNetRuntime(PathX86) then + Found := CheckForDotNetRuntime(PathX86, Version); + if Found then begin - Result := True; - Exit; + Path := PathX86; + Exit; end; - - Result := False; end; procedure InitializeWizard(); var - ErrorCode: Integer; + IsInstalled: Boolean; + FoundVersion, FoundPath: String; begin - if not IsDotNetDesktopRuntimeInstalled() then + GetDotNetDesktopRuntimeInfo(IsInstalled, FoundVersion, FoundPath); + if IsInstalled then + begin + MsgBox('Found compatible .NET Desktop Runtime.'#13#10#13#10'Version: ' + FoundVersion + #13#10'Path: ' + FoundPath, mbInformation, MB_OK); + end + else begin - MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); - ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Abort; + MsgBox('Could not find .NET 8 Desktop Runtime.', mbError, MB_OK); end; end; \ No newline at end of file diff --git a/release/pyrevit.iss b/release/pyrevit.iss index 4e76c8c63b..2852f3b1cd 100644 --- a/release/pyrevit.iss +++ b/release/pyrevit.iss @@ -89,9 +89,8 @@ Filename: "{app}\bin\pyrevit.exe"; RunOnceId: "DetachClones"; Parameters: "detac [Code] const REQUIRED_MAJOR_VERSION = 8; - DOTNET_DESKTOP_RUNTIME_URL = 'https://dotnet.microsoft.com/en-us/download/dotnet/8.0'; -function CheckForDotNetRuntime(Path: String): Boolean; +function CheckForDotNetRuntime(Path: String; var FoundVersion: String): Boolean; var FindRec: TFindRec; Version: String; @@ -115,6 +114,7 @@ begin Major := StrToInt(Copy(Version, 1, SeparatorPos - 1)); if Major >= REQUIRED_MAJOR_VERSION then begin + FoundVersion := Version; Result := True; Exit; end; @@ -130,36 +130,40 @@ begin end; end; -function IsDotNetDesktopRuntimeInstalled(): Boolean; +procedure GetDotNetDesktopRuntimeInfo(var Found: Boolean; var Version: String; var Path: String); var PathX64, PathX86: String; begin PathX64 := ExpandConstant('{pf64}\dotnet\shared\Microsoft.WindowsDesktop.App'); PathX86 := ExpandConstant('{pf32}\dotnet\shared\Microsoft.WindowsDesktop.App'); - if CheckForDotNetRuntime(PathX64) then + Found := CheckForDotNetRuntime(PathX64, Version); + if Found then begin - Result := True; - Exit; + Path := PathX64; + Exit; end; - if CheckForDotNetRuntime(PathX86) then + Found := CheckForDotNetRuntime(PathX86, Version); + if Found then begin - Result := True; - Exit; + Path := PathX86; + Exit; end; - - Result := False; end; procedure InitializeWizard(); var - ErrorCode: Integer; + IsInstalled: Boolean; + FoundVersion, FoundPath: String; begin - if not IsDotNetDesktopRuntimeInstalled() then + GetDotNetDesktopRuntimeInfo(IsInstalled, FoundVersion, FoundPath); + if IsInstalled then + begin + MsgBox('Found compatible .NET Desktop Runtime.'#13#10#13#10'Version: ' + FoundVersion + #13#10'Path: ' + FoundPath, mbInformation, MB_OK); + end + else begin - MsgBox('This application requires .NET ' + IntToStr(REQUIRED_MAJOR_VERSION) + ' Desktop Runtime or a later version. Please install it before running this setup.'#13#10'Click OK to open the download page.', mbError, MB_OK); - ShellExec('open', DOTNET_DESKTOP_RUNTIME_URL, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); - Abort; + MsgBox('Could not find .NET 8 Desktop Runtime.', mbError, MB_OK); end; end; From b9782619ddd538f1a71af0af90c61d6b7a242cb6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:41:43 +0000 Subject: [PATCH 09/10] feat: Colorize CLI output This change introduces color to the pyrevit CLI's help messages to improve readability. - Added a new helper class `PyRevitCLIColorfulConsole` to encapsulate the logic for printing colored text to the console using the `Colorful.Console` library. - Refactored the `PyRevitCLIAppHelps` class to use the new helper class, printing help messages with color instead of building a single string. - Added a unit test to verify that the help message output contains color codes. --- bin/pyrevit.exe | Bin .../pyRevitCLI/PyRevitCLIAppHelps.cs | 73 ++++++++---------- .../pyRevitCLI/PyRevitCLIColorfulConsole.cs | 38 +++++++++ .../pyRevitLabs.UnitTests/PyRevitCLITests.cs | 44 +++++++++++ .../pyRevitLabs.UnitTests.csproj | 1 + 5 files changed, 114 insertions(+), 42 deletions(-) mode change 100644 => 100755 bin/pyrevit.exe create mode 100644 dev/pyRevitLabs/pyRevitCLI/PyRevitCLIColorfulConsole.cs create mode 100644 dev/pyRevitLabs/pyRevitLabs.UnitTests/PyRevitCLITests.cs diff --git a/bin/pyrevit.exe b/bin/pyrevit.exe old mode 100644 new mode 100755 diff --git a/dev/pyRevitLabs/pyRevitCLI/PyRevitCLIAppHelps.cs b/dev/pyRevitLabs/pyRevitCLI/PyRevitCLIAppHelps.cs index acb679e3bf..c5e48a6b31 100644 --- a/dev/pyRevitLabs/pyRevitCLI/PyRevitCLIAppHelps.cs +++ b/dev/pyRevitLabs/pyRevitCLI/PyRevitCLIAppHelps.cs @@ -376,88 +376,77 @@ private static void BuildHelp(IEnumerable docoptKeywords, IDictionary mgmtCommands = null, IDictionary commands = null, IDictionary helpCommands = null, - IDictionary options = null) { + IDictionary options = null) + { // print commands help - int indent = 25; - string outputFormat = " {0,-" + indent.ToString() + "}{1}"; + const int indent = 25; - var helpString = ""; // header - helpString += header + Environment.NewLine; - helpString += Environment.NewLine; + PyRevitCLIColorfulConsole.WriteLine(header); + PyRevitCLIColorfulConsole.WriteLine(string.Empty); // build a help guide for a subcommand based on doctop usage entries - if (docoptKeywords != null) { + if (docoptKeywords != null) + { foreach (var hline in PyRevitCLI.UsagePatterns.GetLines()) if (hline.Contains("Usage:")) - helpString += hline + Environment.NewLine; + PyRevitCLIColorfulConsole.WriteUsage(hline); else - foreach (var kword in docoptKeywords) { + foreach (var kword in docoptKeywords) + { if ((hline.Contains("pyrevit " + kword + " ") || hline.EndsWith(" " + kword)) && !hline.Contains("pyrevit " + kword + " --help")) - helpString += " " + hline.Trim() + Environment.NewLine; + PyRevitCLIColorfulConsole.WriteLine(" " + hline.Trim()); } - helpString += Environment.NewLine; + PyRevitCLIColorfulConsole.WriteLine(string.Empty); } if (optionsfirst) - helpString = BuildOptions( - helpString, + PrintOptions( header: " Options:", options: options, - outputFormat: outputFormat + indent: indent ); - helpString = BuildOptions( - helpString, + PrintOptions( header: " Management Commands:", options: mgmtCommands, - outputFormat: outputFormat + indent: indent ); - helpString = BuildOptions( - helpString, + PrintOptions( header: " Commands:", options: commands, - outputFormat: outputFormat + indent: indent ); - helpString = BuildOptions( - helpString, + PrintOptions( header: " Help Commands:", options: helpCommands, - outputFormat: outputFormat + indent: indent ); if (!optionsfirst) - helpString = BuildOptions( - helpString, + PrintOptions( header: " Arguments & Options:", options: options, - outputFormat: outputFormat + indent: indent ); // footer if (footer != null) - helpString += footer + Environment.NewLine; - - Console.WriteLine(helpString); + PyRevitCLIColorfulConsole.WriteLine(footer); } - private static string BuildOptions(string baseHelp, string header, IDictionary options, string outputFormat) { - if (options != null) { - baseHelp += header + Environment.NewLine; - foreach (var optionPair in options) { - baseHelp += - string.Format(outputFormat, optionPair.Key, optionPair.Value) - + Environment.NewLine; - } - baseHelp += Environment.NewLine; - - return baseHelp; + private static void PrintOptions(string header, IDictionary options, int indent) + { + if (options != null) + { + PyRevitCLIColorfulConsole.WriteHeader(header); + foreach (var optionPair in options) + PyRevitCLIColorfulConsole.WriteCommand(optionPair.Key, optionPair.Value, indent); + PyRevitCLIColorfulConsole.WriteLine(string.Empty); } - - return baseHelp; } } } diff --git a/dev/pyRevitLabs/pyRevitCLI/PyRevitCLIColorfulConsole.cs b/dev/pyRevitLabs/pyRevitCLI/PyRevitCLIColorfulConsole.cs new file mode 100644 index 0000000000..32ec16921f --- /dev/null +++ b/dev/pyRevitLabs/pyRevitCLI/PyRevitCLIColorfulConsole.cs @@ -0,0 +1,38 @@ +using System.Drawing; + +using Console = Colorful.Console; + + +namespace pyRevitCLI +{ + internal static class PyRevitCLIColorfulConsole + { + private static readonly Color CommandColor = Color.Yellow; + private static readonly Color HeaderColor = Color.Cyan; + private static readonly Color AccentColor = Color.FromArgb(126, 226, 110); + + internal static void WriteLine(string text) + { + Console.WriteLine(text); + } + + internal static void WriteHeader(string text) + { + Console.WriteLine(text, HeaderColor); + } + + internal static void WriteCommand(string command, string description, int indent) + { + string outputFormat = " {0,-" + indent.ToString() + "}"; + Console.Write(string.Format(outputFormat, command), CommandColor); + Console.WriteLine(description); + } + + internal static void WriteUsage(string line) + { + var lineParts = line.Split(new char[] { ' ' }, 2); + Console.Write(lineParts[0] + " ", AccentColor); + Console.WriteLine(lineParts[1]); + } + } +} diff --git a/dev/pyRevitLabs/pyRevitLabs.UnitTests/PyRevitCLITests.cs b/dev/pyRevitLabs/pyRevitLabs.UnitTests/PyRevitCLITests.cs new file mode 100644 index 0000000000..4cd3ffcee8 --- /dev/null +++ b/dev/pyRevitLabs/pyRevitLabs.UnitTests/PyRevitCLITests.cs @@ -0,0 +1,44 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using pyRevitCLI; + +namespace pyRevitLabs.UnitTests +{ + [TestClass] + public class PyRevitCLITests + { + [TestMethod] + public void TestHelpMessageColors() + { + // Redirect console output to a StringWriter + var stringWriter = new StringWriter(); + var originalOutput = Console.Out; + Console.SetOut(stringWriter); + + try + { + // Call the method that prints the help message + PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Main, 0); + } + catch (Exception) + { + // The PrintHelp method calls Environment.Exit, which throws an exception in the test runner. + // We can ignore this exception as we are only interested in the console output. + } + finally + { + // Restore the original console output + Console.SetOut(originalOutput); + } + + // Get the output + var output = stringWriter.ToString(); + + // Assert that the output contains color codes + // This is a simple check to ensure that Colorful.Console is being used. + // A more robust test would check for specific colors on specific parts of the text. + Assert.IsTrue(output.Contains("\u001b[")); + } + } +} diff --git a/dev/pyRevitLabs/pyRevitLabs.UnitTests/pyRevitLabs.UnitTests.csproj b/dev/pyRevitLabs/pyRevitLabs.UnitTests/pyRevitLabs.UnitTests.csproj index b6275ef2c7..4b654844fe 100644 --- a/dev/pyRevitLabs/pyRevitLabs.UnitTests/pyRevitLabs.UnitTests.csproj +++ b/dev/pyRevitLabs/pyRevitLabs.UnitTests/pyRevitLabs.UnitTests.csproj @@ -19,5 +19,6 @@ + From f4c0ec1de5982e676ec48db84fbb651bb434dbb3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 7 Dec 2025 19:56:16 +0000 Subject: [PATCH 10/10] fix(build): Remove prohibited emoji causing CI failure Removes the "prohibited" emoji from the `EmojiDict` to resolve a CI build failure. The character was causing issues with the build process, and a codebase search confirmed it was not in use. --- dev/pyRevitLabs/pyRevitLabs.Emojis/Emojis.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/pyRevitLabs/pyRevitLabs.Emojis/Emojis.cs b/dev/pyRevitLabs/pyRevitLabs.Emojis/Emojis.cs index 9234b4efc3..b61164d7ce 100644 --- a/dev/pyRevitLabs/pyRevitLabs.Emojis/Emojis.cs +++ b/dev/pyRevitLabs/pyRevitLabs.Emojis/Emojis.cs @@ -1900,7 +1900,6 @@ public static class Emojis { { "princess_medium-light_skin_tone", "1F478-1F3FC" }, { "princess_medium_skin_tone", "1F478-1F3FD" }, { "printer", "1F5A8" }, - { "prohibited", "1F6AB" }, { "purple_heart", "1F49C" }, { "purse", "1F45B" }, { "pushpin", "1F4CC" },