Skip to content

Commit a4a5eb3

Browse files
committed
fix: installer .NET detection, remove item outlines, bump to v1.3.2
- Installer now checks 6 locations (fs paths + registry) for .NET 8 Desktop Runtime; adds "Continue anyway" bypass when auto-detect fails - Remove WPF default focus visual (grey pointy outline) from list items via FocusVisualStyle="{x:Null}"; increase corner radius to 6 px - Consolidate 1.3.1/1.3.2/1.3.3 fixes into a single clean 1.3.2 release
1 parent 021d63a commit a4a5eb3

4 files changed

Lines changed: 118 additions & 47 deletions

File tree

CHANGELOG.md

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
## [1.3.3] - 2026-04-15
11-
12-
### Fixed
13-
- **Search icon** — Replaced the 🔍 emoji (rendered poorly on most DPI settings) with the
14-
native Segoe MDL2 Assets "Search" glyph (``). Crisp at all scales.
15-
- **Sidebar background preserved on Windows 11** — Acrylic backdrop no longer replaces the
16-
dark `#CC1A1A1A` theme with a washed-out grey system tint. The DWM backdrop type is
17-
applied without extending the frame or clearing the border background; acrylic adds subtle
18-
depth through the 20% transparency while the dark theme remains intact.
19-
2010
## [1.3.2] - 2026-04-15
2111

2212
### Fixed
23-
- **Standalone EXE now works** — Native DLLs (SQLite, WPF) were previously excluded
24-
from the single-file bundle (`IncludeNativeLibrariesForSelfExtract=false`), causing the
25-
standalone EXE to crash on launch. All dependencies are now embedded.
26-
- **Uninstaller now quits the app first** — ClipHive is forcefully terminated via
27-
`taskkill` before file removal, ensuring a clean uninstall with no locked-file errors.
28-
- **Duplicate clipboard entries** — Copying the same content multiple times no longer
29-
adds duplicate rows. The existing entry is bumped to the top instead (timestamp
30-
updated). Uses a SHA-256 content hash per row — no decryption overhead on copy.
13+
- **Installer .NET detection** — Detection now checks six distinct locations (system-wide
14+
64-bit path, hard-coded `C:\Program Files\dotnet`, 32-bit path, per-user install path,
15+
registry `HKLM\SOFTWARE\dotnet\Setup\...`, and WOW6432Node). If all checks fail but
16+
the user knows .NET is installed, a new "Continue anyway" option lets them proceed
17+
without being hard-blocked.
18+
- **Item outlines / pointy corners** — WPF's default dotted focus rectangle (grey square
19+
outline around selected items) is suppressed via `FocusVisualStyle="{x:Null}"`. Item
20+
corners are now rounded (6 px radius) with no border, giving a clean card look.
21+
- **Search icon** — Replaced emoji with native Segoe MDL2 Assets glyph (``).
22+
Crisp at all DPI settings.
23+
- **Sidebar background on Windows 11** — Acrylic backdrop no longer overwrites the dark
24+
`#CC1A1A1A` theme with a washed-out system grey tint.
25+
- **Standalone EXE** — Native DLLs (SQLite, WPF) are now embedded; standalone no longer
26+
crashes on launch.
27+
- **Uninstaller** — ClipHive is forcefully terminated via `taskkill` before file removal,
28+
ensuring a clean uninstall with no locked-file errors.
29+
- **Duplicate clipboard entries** — Copying the same content multiple times no longer adds
30+
duplicate rows. The existing entry is bumped to the top (timestamp updated) using a
31+
SHA-256 content hash — no decryption overhead on copy.
3132

3233
### Changed
33-
- **Two release artifacts** with different size/dependency trade-offs:
34+
- **Two release artifacts:**
3435
- **Setup installer** (~20 MB) — framework-dependent; requires .NET 8 Windows Desktop
35-
Runtime (installer checks and opens the download page if missing).
36-
- **Standalone EXE** (~90 MB) — self-contained + compressed; no .NET required.
37-
- Standalone EXE compressed with `EnableCompressionInSingleFile=true`, dropped
38-
`PublishReadyToRun` — size reduced from ~225 MB to ~90 MB.
36+
Runtime. Installer checks multiple locations and offers "Continue anyway" if auto-
37+
detection cannot find an existing install.
38+
- **Standalone EXE** (~90 MB) — fully self-contained with compressed runtime; no .NET
39+
installation required.
3940

40-
## [1.3.1] - 2026-04-15
41-
42-
### Fixed
43-
- **Build fix** — Replaced `ICSharpCode.AvalonEdit` (version 6.x unavailable on nuget.org)
44-
with a plain read-only `TextBox` for the code detail panel. The "⌄ view" feature works
45-
identically — scrollable monospace panel — without the external dependency.
41+
### Build
42+
- Replaced `ICSharpCode.AvalonEdit` (unavailable on NuGet) with a plain read-only
43+
`TextBox` for the code detail panel. Feature is identical — scrollable monospace view.
4644

4745
## [1.3.0] - 2026-04-15
4846

@@ -151,6 +149,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
151149
- Inno Setup installer with repair/uninstall detection
152150
- Zero network calls — no telemetry, no cloud sync
153151

154-
[Unreleased]: https://github.com/levitasOrg/cliphive/compare/v1.2.0...HEAD
152+
[Unreleased]: https://github.com/levitasOrg/cliphive/compare/v1.3.2...HEAD
153+
[1.3.2]: https://github.com/levitasOrg/cliphive/compare/v1.3.0...v1.3.2
154+
[1.3.0]: https://github.com/levitasOrg/cliphive/compare/v1.2.0...v1.3.0
155155
[1.2.0]: https://github.com/levitasOrg/cliphive/compare/v1.0.0...v1.2.0
156156
[1.0.0]: https://github.com/levitasOrg/cliphive/releases/tag/v1.0.0

installer/ClipHive.iss

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#define MyAppName "ClipHive"
2-
#define MyAppVersion "1.3.3"
2+
#define MyAppVersion "1.3.2"
33
#define MyAppPublisher "ClipHive Contributors"
44
#define MyAppURL "https://github.com/levitasOrg/cliphive"
55
#define MyAppExeName "ClipHive.exe"
@@ -60,17 +60,75 @@ Type: filesandordirs; Name: "{localappdata}\ClipHive"
6060
[Code]
6161
6262
// ─── .NET 8 Desktop Runtime check ───────────────────────────────────────────
63+
// Tries multiple locations because .NET can be installed by the SDK, by VS,
64+
// by winget, or by a standalone runtime installer — each may land in a
65+
// different folder. Falls back to registry when no folder is found.
6366
6467
function IsDotNet8DesktopInstalled(): Boolean;
6568
var
6669
FindRec: TFindRec;
70+
VersionNames: TArrayOfString;
71+
I: Integer;
6772
begin
6873
Result := False;
69-
// Check for any 8.x.y folder under the Windows Desktop App shared runtime
74+
75+
// 1 — Standard 64-bit system-wide install path
7076
if FindFirst(ExpandConstant('{commonpf64}\dotnet\shared\Microsoft.WindowsDesktop.App\8.*'), FindRec) then
7177
begin
78+
FindClose(FindRec);
7279
Result := True;
80+
Exit;
81+
end;
82+
83+
// 2 — Hard-coded path (in case {commonpf64} resolves differently)
84+
if FindFirst('C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\8.*', FindRec) then
85+
begin
7386
FindClose(FindRec);
87+
Result := True;
88+
Exit;
89+
end;
90+
91+
// 3 — 32-bit program files (rare but possible)
92+
if FindFirst(ExpandConstant('{commonpf32}\dotnet\shared\Microsoft.WindowsDesktop.App\8.*'), FindRec) then
93+
begin
94+
FindClose(FindRec);
95+
Result := True;
96+
Exit;
97+
end;
98+
99+
// 4 — Per-user install path (dotnet install script with --user flag)
100+
if FindFirst(ExpandConstant('{localappdata}\Microsoft\dotnet\shared\Microsoft.WindowsDesktop.App\8.*'), FindRec) then
101+
begin
102+
FindClose(FindRec);
103+
Result := True;
104+
Exit;
105+
end;
106+
107+
// 5 — Registry: HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App
108+
// .NET registers a DWORD value named "8.x.y" = 1 for each installed version
109+
if RegGetValueNames(HKLM, 'SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App', VersionNames) then
110+
begin
111+
for I := 0 to GetArrayLength(VersionNames) - 1 do
112+
begin
113+
if (Length(VersionNames[I]) >= 2) and (Copy(VersionNames[I], 1, 2) = '8.') then
114+
begin
115+
Result := True;
116+
Exit;
117+
end;
118+
end;
119+
end;
120+
121+
// 6 — Registry WOW6432Node fallback
122+
if RegGetValueNames(HKLM, 'SOFTWARE\WOW6432Node\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App', VersionNames) then
123+
begin
124+
for I := 0 to GetArrayLength(VersionNames) - 1 do
125+
begin
126+
if (Length(VersionNames[I]) >= 2) and (Copy(VersionNames[I], 1, 2) = '8.') then
127+
begin
128+
Result := True;
129+
Exit;
130+
end;
131+
end;
74132
end;
75133
end;
76134
@@ -112,16 +170,26 @@ begin
112170
if not IsDotNet8DesktopInstalled() then
113171
begin
114172
Answer := MsgBox(
115-
'ClipHive requires the .NET 8 Windows Desktop Runtime, which was not found.' + #13#10 + #13#10 +
116-
'Click Yes to open the Microsoft download page, then re-run this installer.' + #13#10 +
117-
'Click No to cancel.',
118-
mbError, MB_YESNO);
119-
if Answer = IDYES then
173+
'The .NET 8 Windows Desktop Runtime was not detected on this system.' + #13#10 + #13#10 +
174+
'If you already have it installed (e.g. via SDK or Visual Studio), ' +
175+
'click Yes to continue the installation anyway.' + #13#10 + #13#10 +
176+
'Click No to open the Microsoft download page first, then re-run this installer.' + #13#10 +
177+
'Click Cancel to exit.',
178+
mbConfirmation, MB_YESNOCANCEL);
179+
if Answer = IDNO then
180+
begin
120181
ShellExec('open',
121182
'https://dotnet.microsoft.com/download/dotnet/8.0',
122183
'', '', SW_SHOWNORMAL, ewNoWait, ResultCode);
123-
Result := False;
124-
Exit;
184+
Result := False;
185+
Exit;
186+
end;
187+
if Answer = IDCANCEL then
188+
begin
189+
Result := False;
190+
Exit;
191+
end;
192+
// Answer = IDYES → user says it's installed, continue anyway
125193
end;
126194
127195
if not IsAlreadyInstalled() then

src/ClipHive/ClipHive.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
1111
<RootNamespace>ClipHive</RootNamespace>
1212
<AssemblyName>ClipHive</AssemblyName>
13-
<Version>1.3.3</Version>
14-
<FileVersion>1.3.3.0</FileVersion>
13+
<Version>1.3.2</Version>
14+
<FileVersion>1.3.2.0</FileVersion>
1515
<Copyright>Copyright © 2026 ClipHive</Copyright>
1616
<Description>Lightweight clipboard history manager for Windows</Description>
1717
<Company>ClipHive</Company>

src/ClipHive/Resources/Styles.xaml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,22 @@
7777

7878
<!-- ─── Clipboard Item ListBoxItem ────────────────────────────────────── -->
7979
<Style x:Key="ClipItemStyle" TargetType="ListBoxItem">
80-
<Setter Property="Background" Value="Transparent" />
81-
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}" />
82-
<Setter Property="Padding" Value="10,6" />
83-
<Setter Property="Cursor" Value="Hand" />
80+
<Setter Property="Background" Value="Transparent" />
81+
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}" />
82+
<Setter Property="Padding" Value="10,6" />
83+
<Setter Property="Cursor" Value="Hand" />
8484
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
85+
<!-- Remove WPF's default dotted-rectangle focus visual (grey pointy outline) -->
86+
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
8587
<Setter Property="Template">
8688
<Setter.Value>
8789
<ControlTemplate TargetType="ListBoxItem">
8890
<Border x:Name="ItemBorder"
8991
Background="{TemplateBinding Background}"
92+
BorderThickness="0"
9093
Padding="{TemplateBinding Padding}"
91-
CornerRadius="4"
92-
Margin="4,1">
94+
CornerRadius="6"
95+
Margin="6,1">
9396
<ContentPresenter />
9497
</Border>
9598
<ControlTemplate.Triggers>

0 commit comments

Comments
 (0)