From 41b3725faacdea55b5dfd0ff45a8fa4e827c14de Mon Sep 17 00:00:00 2001 From: Frozd Date: Tue, 10 Mar 2026 17:13:42 +0100 Subject: [PATCH] feat(autoupdate): detect install type --- CarManager3Setup/CarManager3Setup.vdproj | 28 +++++- CarManagerV3/CarManagerV3.csproj | 11 ++- CarManagerV3/Forms/MainForm.cs | 16 +++- CarManagerV3/Forms/SettingsForm.Designer.cs | 94 ++++++++++++++------- CarManagerV3/Forms/SettingsForm.cs | 3 + CarManagerV3/Util/InstallModeDetector.cs | 38 +++++++++ 6 files changed, 151 insertions(+), 39 deletions(-) create mode 100644 CarManagerV3/Util/InstallModeDetector.cs diff --git a/CarManager3Setup/CarManager3Setup.vdproj b/CarManager3Setup/CarManager3Setup.vdproj index 8e4d452..0d97cd1 100644 --- a/CarManager3Setup/CarManager3Setup.vdproj +++ b/CarManager3Setup/CarManager3Setup.vdproj @@ -333,7 +333,7 @@ "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:Car Manager 3" "ProductCode" = "8:{24769DBA-B806-4E47-9F4C-17BC8AD0528E}" - "PackageCode" = "8:{741BAAEC-3EE7-46C4-94AB-575C677186BB}" + "PackageCode" = "8:{6A7873AB-8003-4584-9969-B4AA7C461623}" "UpgradeCode" = "8:{6FF57925-465E-4DB9-85DA-CE933191A3DD}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" @@ -413,10 +413,32 @@ "Name" = "8:[Manufacturer]" "Condition" = "8:" "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" + "DeleteAtUninstall" = "11:TRUE" "Transitive" = "11:FALSE" "Keys" { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_022FD53D0D4C4621A160F70F2E4A81DE" + { + "Name" = "8:CarManager3" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:TRUE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + "{ADCFDA98-8FDD-45E4-90BC-E3D20B029870}:_22123BF42909409F8D665A142188737C" + { + "Name" = "8:InstallType" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "ValueTypes" = "3:1" + "Value" = "8:MSI" + } + } + } } "Values" { @@ -1036,7 +1058,7 @@ { "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_A6F761D38264485ABAB61B553E1CAE3C" { - "SourcePath" = "8:..\\CarManagerV3\\bin\\Release\\net8.0-windows\\win-x64\\publish\\CarManagerV3.exe" + "SourcePath" = "8:..\\CarManagerV3\\bin\\Debug\\net8.0-windows\\win-x64\\publish\\CarManagerV3.exe" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_B69138933B80450EA18D704C54E8913F" diff --git a/CarManagerV3/CarManagerV3.csproj b/CarManagerV3/CarManagerV3.csproj index 2f26333..ad7563d 100644 --- a/CarManagerV3/CarManagerV3.csproj +++ b/CarManagerV3/CarManagerV3.csproj @@ -15,7 +15,7 @@ false true 0 - 1.4.1 + 1.4.2 false false true @@ -23,9 +23,12 @@ true true CarMgm_Icon.ico - Car Manager 3 - Car Manager 3 - 1.4.1 + CarManager3 + CarManager3 + 1.4.2 + Jaro Digital + Jaro Digital + Car Manager 3 diff --git a/CarManagerV3/Forms/MainForm.cs b/CarManagerV3/Forms/MainForm.cs index 5b097ad..265f105 100644 --- a/CarManagerV3/Forms/MainForm.cs +++ b/CarManagerV3/Forms/MainForm.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using CarManagerV3.Forms; using CarManagerV3.Manager; +using CarManagerV3.Util; namespace CarManagerV3 { @@ -65,8 +66,19 @@ namespace CarManagerV3 { if (Updater.IsUpdateAvailable(Properties.Settings.Default.AllowPrerelease)) { - UpdatePromptForm updatePrompt = new UpdatePromptForm(Updater.GetCurrentVersion(true), Updater.GetLatestVersion(Properties.Settings.Default.AllowPrerelease)); - updatePrompt.ShowDialog(); + if (InstallModeDetector.IsInstalledViaMsi()) + { + UpdatePromptForm updatePrompt = new UpdatePromptForm(Updater.GetCurrentVersion(true), Updater.GetLatestVersion(Properties.Settings.Default.AllowPrerelease)); + updatePrompt.ShowDialog(); + } else + { + DialogResult updateResult = MessageBox.Show($"A new version of Car Manager is available! \nYour Version: {Updater.GetCurrentVersion(true)} \nLatest Version: {Updater.GetLatestVersion(Properties.Settings.Default.AllowPrerelease)} \n\nDo you want to open the Git repository to download the update?", "Update Available", MessageBoxButtons.YesNo, MessageBoxIcon.Information); + if (updateResult == DialogResult.Yes) + { + Updater.OpenReleasePage(Updater.GetLatestVersion(Properties.Settings.Default.AllowPrerelease)); + } + } + } } catch (Exception ex) diff --git a/CarManagerV3/Forms/SettingsForm.Designer.cs b/CarManagerV3/Forms/SettingsForm.Designer.cs index 2e76ba3..39c8b3b 100644 --- a/CarManagerV3/Forms/SettingsForm.Designer.cs +++ b/CarManagerV3/Forms/SettingsForm.Designer.cs @@ -38,13 +38,16 @@ tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); lblDataLocation = new System.Windows.Forms.Label(); tbxDataLocation = new System.Windows.Forms.TextBox(); + cbxPreRelease = new System.Windows.Forms.CheckBox(); tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); btnReset = new System.Windows.Forms.Button(); - cbxPreRelease = new System.Windows.Forms.CheckBox(); + flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); + lblEnv = new System.Windows.Forms.Label(); flowLayoutPanel1.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); tableLayoutPanel1.SuspendLayout(); tableLayoutPanel2.SuspendLayout(); + flowLayoutPanel3.SuspendLayout(); SuspendLayout(); // // flowLayoutPanel1 @@ -84,10 +87,10 @@ flowLayoutPanel2.Controls.Add(btnDiscard); flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; flowLayoutPanel2.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; - flowLayoutPanel2.Location = new System.Drawing.Point(249, 0); + flowLayoutPanel2.Location = new System.Drawing.Point(249, 30); flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); flowLayoutPanel2.Name = "flowLayoutPanel2"; - flowLayoutPanel2.Size = new System.Drawing.Size(240, 64); + flowLayoutPanel2.Size = new System.Drawing.Size(240, 44); flowLayoutPanel2.TabIndex = 2; // // btnAccept @@ -151,33 +154,6 @@ tbxDataLocation.Size = new System.Drawing.Size(365, 27); tbxDataLocation.TabIndex = 1; // - // tableLayoutPanel2 - // - tableLayoutPanel2.ColumnCount = 2; - tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - tableLayoutPanel2.Controls.Add(flowLayoutPanel2, 1, 0); - tableLayoutPanel2.Controls.Add(btnReset, 0, 0); - tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom; - tableLayoutPanel2.Location = new System.Drawing.Point(0, 553); - tableLayoutPanel2.Name = "tableLayoutPanel2"; - tableLayoutPanel2.Padding = new System.Windows.Forms.Padding(10, 0, 10, 0); - tableLayoutPanel2.RowCount = 1; - tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - tableLayoutPanel2.Size = new System.Drawing.Size(499, 64); - tableLayoutPanel2.TabIndex = 4; - // - // btnReset - // - btnReset.AutoSize = true; - btnReset.Location = new System.Drawing.Point(13, 3); - btnReset.Name = "btnReset"; - btnReset.Size = new System.Drawing.Size(130, 30); - btnReset.TabIndex = 3; - btnReset.Text = "Revert to default"; - btnReset.UseVisualStyleBackColor = true; - btnReset.Click += btnReset_Click; - // // cbxPreRelease // cbxPreRelease.AutoSize = true; @@ -190,6 +166,59 @@ cbxPreRelease.Text = "Pre-Release channel"; cbxPreRelease.UseVisualStyleBackColor = true; // + // tableLayoutPanel2 + // + tableLayoutPanel2.AutoSize = true; + tableLayoutPanel2.ColumnCount = 2; + tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + tableLayoutPanel2.Controls.Add(flowLayoutPanel2, 1, 1); + tableLayoutPanel2.Controls.Add(btnReset, 0, 1); + tableLayoutPanel2.Controls.Add(flowLayoutPanel3, 0, 0); + tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom; + tableLayoutPanel2.Location = new System.Drawing.Point(0, 543); + tableLayoutPanel2.Name = "tableLayoutPanel2"; + tableLayoutPanel2.Padding = new System.Windows.Forms.Padding(10, 0, 10, 0); + tableLayoutPanel2.RowCount = 2; + tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + tableLayoutPanel2.Size = new System.Drawing.Size(499, 74); + tableLayoutPanel2.TabIndex = 4; + // + // btnReset + // + btnReset.AutoSize = true; + btnReset.Location = new System.Drawing.Point(13, 33); + btnReset.Name = "btnReset"; + btnReset.Size = new System.Drawing.Size(130, 30); + btnReset.TabIndex = 3; + btnReset.Text = "Revert to default"; + btnReset.UseVisualStyleBackColor = true; + btnReset.Click += btnReset_Click; + // + // flowLayoutPanel3 + // + flowLayoutPanel3.AutoSize = true; + flowLayoutPanel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + tableLayoutPanel2.SetColumnSpan(flowLayoutPanel3, 2); + flowLayoutPanel3.Controls.Add(lblEnv); + flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + flowLayoutPanel3.Location = new System.Drawing.Point(10, 5); + flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0, 5, 0, 5); + flowLayoutPanel3.Name = "flowLayoutPanel3"; + flowLayoutPanel3.Size = new System.Drawing.Size(479, 20); + flowLayoutPanel3.TabIndex = 4; + // + // lblEnv + // + lblEnv.AutoSize = true; + lblEnv.ForeColor = System.Drawing.SystemColors.GrayText; + lblEnv.Location = new System.Drawing.Point(3, 0); + lblEnv.Name = "lblEnv"; + lblEnv.Size = new System.Drawing.Size(131, 20); + lblEnv.TabIndex = 0; + lblEnv.Text = "Environment: %E%"; + // // SettingsForm // AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); @@ -213,7 +242,10 @@ tableLayoutPanel1.PerformLayout(); tableLayoutPanel2.ResumeLayout(false); tableLayoutPanel2.PerformLayout(); + flowLayoutPanel3.ResumeLayout(false); + flowLayoutPanel3.PerformLayout(); ResumeLayout(false); + PerformLayout(); } #endregion @@ -230,5 +262,7 @@ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.Button btnReset; private System.Windows.Forms.CheckBox cbxPreRelease; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3; + private System.Windows.Forms.Label lblEnv; } } \ No newline at end of file diff --git a/CarManagerV3/Forms/SettingsForm.cs b/CarManagerV3/Forms/SettingsForm.cs index dc5bdcc..67634bf 100644 --- a/CarManagerV3/Forms/SettingsForm.cs +++ b/CarManagerV3/Forms/SettingsForm.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using CarManagerV3.Util; namespace CarManagerV3.Forms { @@ -42,6 +43,8 @@ namespace CarManagerV3.Forms read: () => Properties.Settings.Default.AllowPrerelease, write: v => Properties.Settings.Default.AllowPrerelease = v); + lblEnv.Text = lblEnv.Text.Replace("%E%", InstallModeDetector.IsInstalledViaMsi() ? "Installed via MSI" : "Running in portable mode"); + } private void SettingsForm_Load(object sender, EventArgs e) diff --git a/CarManagerV3/Util/InstallModeDetector.cs b/CarManagerV3/Util/InstallModeDetector.cs new file mode 100644 index 0000000..acefda1 --- /dev/null +++ b/CarManagerV3/Util/InstallModeDetector.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Microsoft.Win32; + +namespace CarManagerV3.Util +{ + public static class InstallModeDetector + { + private const string _keyPath = @"Software\Jaro Digital\CarManager3"; + private const string KeyPath = _keyPath; + private const string ValueName = "InstallType"; + + public static bool IsInstalledViaMsi() + { + // Prefer HKLM if your MSI is per-machine; fallback to HKCU if per-user. + System.Diagnostics.Debug.WriteLine($"Checking registry for install type at HKLM\\{KeyPath} and HKCU\\{KeyPath}"); + object? val = + Registry.GetValue($@"HKEY_LOCAL_MACHINE\{KeyPath}", ValueName, null) + ?? Registry.GetValue($@"HKEY_CURRENT_USER\{KeyPath}", ValueName, null); + + return val is string s && string.Equals(s, "MSI", StringComparison.OrdinalIgnoreCase); + } + + public static bool IsPortable() => !IsInstalledViaMsi(); + + public static string GetInstallType() + { + object? val = + Registry.GetValue($@"HKEY_LOCAL_MACHINE\{KeyPath}", ValueName, null) + ?? Registry.GetValue($@"HKEY_CURRENT_USER\{KeyPath}", ValueName, null); + return val as string ?? "Unknown"; + } + } +}