From b09c23b4ee8dbde62365e5ff30d28631317add72 Mon Sep 17 00:00:00 2001 From: WillowDev <216433317+willowdev-code@users.noreply.github.com> Date: Mon, 26 Oct 2026 16:54:03 +0100 Subject: [PATCH 1/3] Icon for the exe and setup; xpp-lens console entry in the Start menu --- CHANGELOG.md | 8 +++ README.md | 2 +- README.pl.md | 2 +- packaging/icon/icon.png | Bin 0 -> 17775 bytes packaging/icon/make-icon.ps1 | 100 +++++++++++++++++++++++++++++++++++ packaging/icon/xpplens.ico | Bin 0 -> 24323 bytes packaging/inno/xpp-lens.iss | 6 +++ src/XppLens/XppLens.csproj | 2 + 8 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 packaging/icon/icon.png create mode 100644 packaging/icon/make-icon.ps1 create mode 100644 packaging/icon/xpplens.ico diff --git a/CHANGELOG.md b/CHANGELOG.md index 3295a4c..dc48f86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to xpp-lens (called xpp-graft up to 1.2.0). Versions follow `` in `src/XppLens/XppLens.csproj`; release tags are `vX.Y.Z`. +## 1.3.3 + +### Added +- An icon (a lens over X++ on a violet tile) for `xpplens.exe`, the setup program, the Start menu and Windows' + installed apps; drawn by `packaging/icon/make-icon.ps1`. +- Start menu entry `xpp-lens`: a console that shows the command list and takes any `xpplens` command, also right + after installing, before Explorer picks up the new PATH. + ## 1.3.2 — 2026-10-26 ### Fixed diff --git a/README.md b/README.md index 0e96dae..d44289b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The install package is not part of the repository (`dist\` is excluded by `.giti **A. Setup program** (from 1.3.0) — download `xpp-lens-setup-X.Y.Z.exe` from the **Releases** tab and run it. A wizard in Polish or English, for the current user, no administrator rights: it finds `PackagesLocalDirectory`, asks for the label languages and whether to index the Microsoft standard, registers xpp-lens in Claude and offers to build the -index. It puts `xpplens` on your PATH, adds Start menu entries (status, update the index, check for updates) and an +index. It puts `xpplens` on your PATH, adds Start menu entries (an `xpp-lens` console with the command list, status, update the index, check for updates) and an entry in Windows' installed apps. An installation made by `install.ps1` in `C:\Tools\xpp-lens` is taken over in place, with its settings and index. The program is not signed yet: when Windows shows "Windows protected your PC", choose "More info" → "Run anyway". diff --git a/README.pl.md b/README.pl.md index 92b6c55..5753b9c 100644 --- a/README.pl.md +++ b/README.pl.md @@ -18,7 +18,7 @@ Paczki instalacyjnej nie ma w repozytorium (`dist\` jest pomijany przez `.gitign **A. Instalator** (od 1.3.0) — pobierz `xpp-lens-setup-X.Y.Z.exe` z zakładki **Releases** i uruchom. Kreator po polsku albo po angielsku, dla bieżącego użytkownika, bez uprawnień administratora: wykrywa `PackagesLocalDirectory`, pyta o języki etykiet i o indeksowanie standardu Microsoftu, rejestruje xpp-lens w Claude i proponuje zbudowanie indeksu. -Dopisuje `xpplens` do PATH, dodaje skróty w menu Start (status, aktualizacja indeksu, sprawdzenie aktualizacji) i wpis +Dopisuje `xpplens` do PATH, dodaje skróty w menu Start (konsola `xpp-lens` z listą poleceń, status, aktualizacja indeksu, sprawdzenie aktualizacji) i wpis w „Aplikacjach” Windows. Instalację zrobioną przez `install.ps1` w `C:\Tools\xpp-lens` przejmuje w miejscu, razem z ustawieniami i indeksem. Program nie jest jeszcze podpisany: gdy Windows pokaże „System Windows ochronił komputer”, wybierz „Więcej informacji” → „Uruchom mimo to”. diff --git a/packaging/icon/icon.png b/packaging/icon/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7eb8396551f1b866e2e06a532f1763c442b17d3f GIT binary patch literal 17775 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 +$ErrorActionPreference = 'Stop' +Add-Type -AssemblyName System.Drawing + +function New-RoundedRect([float] $x, [float] $y, [float] $w, [float] $h, [float] $r) { + $p = New-Object System.Drawing.Drawing2D.GraphicsPath + $d = 2 * $r + $p.AddArc($x, $y, $d, $d, 180, 90) + $p.AddArc($x + $w - $d, $y, $d, $d, 270, 90) + $p.AddArc($x + $w - $d, $y + $h - $d, $d, $d, 0, 90) + $p.AddArc($x, $y + $h - $d, $d, $d, 90, 90) + $p.CloseFigure() + return $p +} + +function New-IconBitmap([int] $size) { + $bmp = New-Object System.Drawing.Bitmap $size, $size, ([System.Drawing.Imaging.PixelFormat]::Format32bppArgb) + $g = [System.Drawing.Graphics]::FromImage($bmp) + $g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias + $g.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality + $g.Clear([System.Drawing.Color]::Transparent) + $s = [float] $size + + # Tile: violet, lighter at the top. + $margin = [Math]::Max(0.5, $s * 0.03) + $tile = New-RoundedRect $margin $margin ($s - 2 * $margin) ($s - 2 * $margin) ($s * 0.2) + $grad = New-Object System.Drawing.Drawing2D.LinearGradientBrush (New-Object System.Drawing.PointF 0, 0), (New-Object System.Drawing.PointF 0, $s), + ([System.Drawing.Color]::FromArgb(255, 134, 76, 204)), ([System.Drawing.Color]::FromArgb(255, 78, 36, 138)) + $g.FillPath($grad, $tile) + + $white = [System.Drawing.Color]::White + # Lens: a ring, centred a little up and left, with a handle to the bottom right. + $cx = $s * 0.43; $cy = $s * 0.43; $r = $s * 0.24 + $ring = [Math]::Max(1.5, $s * 0.075) + if ($size -ge 24) { + # An X inside the lens (left out at 16-20 px, where it would blur into the ring). + $x = New-Object System.Drawing.Pen $white, ([Math]::Max(1.5, $s * 0.06)) + $x.StartCap = [System.Drawing.Drawing2D.LineCap]::Round + $x.EndCap = [System.Drawing.Drawing2D.LineCap]::Round + $a = $r * 0.4 + $g.DrawLine($x, $cx - $a, $cy - $a, $cx + $a, $cy + $a) + $g.DrawLine($x, $cx - $a, $cy + $a, $cx + $a, $cy - $a) + } + if ($size -ge 32) { + # "++" below the lens, left of the handle: together X++. + $plus = New-Object System.Drawing.Pen $white, ([Math]::Max(1.5, $s * 0.05)) + $plus.StartCap = [System.Drawing.Drawing2D.LineCap]::Round + $plus.EndCap = [System.Drawing.Drawing2D.LineCap]::Round + $p = $s * 0.055; $py = $s * 0.83 + foreach ($px in ($s * 0.24), ($s * 0.42)) { + $g.DrawLine($plus, $px - $p, $py, $px + $p, $py) + $g.DrawLine($plus, $px, $py - $p, $px, $py + $p) + } + } + $pen = New-Object System.Drawing.Pen $white, $ring + $g.DrawEllipse($pen, $cx - $r, $cy - $r, 2 * $r, 2 * $r) + $handle = New-Object System.Drawing.Pen $white, ([Math]::Max(2, $s * 0.11)) + $handle.StartCap = [System.Drawing.Drawing2D.LineCap]::Round + $handle.EndCap = [System.Drawing.Drawing2D.LineCap]::Round + $a = 0.7071 * ($r + $ring / 2) + $g.DrawLine($handle, $cx + $a, $cy + $a, $s * 0.76, $s * 0.76) + $g.Dispose() + return $bmp +} + +$dir = $PSScriptRoot +$sizes = 16, 20, 24, 32, 40, 48, 64, 128, 256 +$frames = foreach ($n in $sizes) { + $bmp = New-IconBitmap $n + $ms = New-Object System.IO.MemoryStream + $bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png) + $bmp.Dispose() + , $ms.ToArray() +} + +# ICO: header, one directory entry per size, then the PNG frames. +$out = New-Object System.IO.MemoryStream +$w = New-Object System.IO.BinaryWriter $out +$w.Write([UInt16]0); $w.Write([UInt16]1); $w.Write([UInt16]$sizes.Count) +$offset = 6 + 16 * $sizes.Count +for ($i = 0; $i -lt $sizes.Count; $i++) { + $n = $sizes[$i] + $dim = if ($n -ge 256) { 0 } else { $n } + $w.Write([byte]$dim); $w.Write([byte]$dim); $w.Write([byte]0); $w.Write([byte]0) + $w.Write([UInt16]1); $w.Write([UInt16]32) + $w.Write([UInt32]$frames[$i].Length); $w.Write([UInt32]$offset) + $offset += $frames[$i].Length +} +foreach ($f in $frames) { $w.Write($f) } +$w.Flush() +[IO.File]::WriteAllBytes((Join-Path $dir 'xpplens.ico'), $out.ToArray()) + +$big = New-IconBitmap 512 +$big.Save((Join-Path $dir 'icon.png'), [System.Drawing.Imaging.ImageFormat]::Png) +$big.Dispose() +Write-Host "written xpplens.ico and icon.png in $dir" diff --git a/packaging/icon/xpplens.ico b/packaging/icon/xpplens.ico new file mode 100644 index 0000000000000000000000000000000000000000..af244b5a13cbe7de27486e296fba3aff03142571 GIT binary patch literal 24323 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 literal 0 HcmV?d00001 diff --git a/packaging/inno/xpp-lens.iss b/packaging/inno/xpp-lens.iss index 41e7b24..1417093 100644 --- a/packaging/inno/xpp-lens.iss +++ b/packaging/inno/xpp-lens.iss @@ -30,6 +30,7 @@ DisableDirPage=yes DisableProgramGroupPage=yes DefaultGroupName=xpp-lens DisableReadyPage=yes +SetupIconFile={#SourcePath}..\icon\xpplens.ico ; The program folder goes on the user's PATH, so "xpplens" works in any new terminal. ChangesEnvironment=yes PrivilegesRequired=lowest @@ -56,6 +57,9 @@ Source: "{#Source}\*"; DestDir: "{app}"; Flags: recursesubdirs ignoreversion [Icons] ; Start menu: commands open in a console that stays open (xpplens commands work there too). +; "xpp-lens" is the general one: the command list, then any xpplens command (PATH set here too, +; in case Explorer has not picked up the new PATH yet). +Name: "{group}\xpp-lens"; Filename: "{cmd}"; Parameters: "/k ""title xpp-lens & set ""PATH={app}\bin;%PATH%"" & xpplens help"""; WorkingDir: "{%USERPROFILE}"; IconFilename: "{app}\bin\xpplens.exe"; Comment: "{cm:IconConsole}" Name: "{group}\{cm:IconStatus}"; Filename: "{cmd}"; Parameters: "/k """"{app}\bin\xpplens.exe"" status"""; WorkingDir: "{app}"; IconFilename: "{app}\bin\xpplens.exe" Name: "{group}\{cm:IconBuild}"; Filename: "{cmd}"; Parameters: "/k """"{app}\bin\xpplens.exe"" build"""; WorkingDir: "{app}"; IconFilename: "{app}\bin\xpplens.exe" Name: "{group}\{cm:IconUpdate}"; Filename: "{cmd}"; Parameters: "/k """"{app}\bin\xpplens.exe"" update"""; WorkingDir: "{app}"; IconFilename: "{app}\bin\xpplens.exe" @@ -98,6 +102,7 @@ en.BuildNow=Build the index now (a console window shows the progress) en.RestartClaude=Restart Claude Desktop so all its sessions use the new version (interrupts work in progress there) en.OpenReadme=Read how to use xpp-lens en.ReadmeUrl=https://github.com/willowdev-code/xpp-lens#readme +en.IconConsole=Console with the xpplens commands en.IconStatus=xpp-lens - status en.IconBuild=xpp-lens - update the index en.IconUpdate=xpp-lens - check for updates @@ -124,6 +129,7 @@ pl.BuildNow=Zbuduj indeks teraz (okno konsoli pokaże postęp) pl.RestartClaude=Uruchom ponownie Claude Desktop, żeby wszystkie jego sesje używały nowej wersji (przerywa trwającą tam pracę) pl.OpenReadme=Przeczytaj, jak używać xpp-lens pl.ReadmeUrl=https://github.com/willowdev-code/xpp-lens/blob/main/README.pl.md +pl.IconConsole=Konsola z poleceniami xpplens pl.IconStatus=xpp-lens - status pl.IconBuild=xpp-lens - aktualizacja indeksu pl.IconUpdate=xpp-lens - sprawdź aktualizacje diff --git a/src/XppLens/XppLens.csproj b/src/XppLens/XppLens.csproj index d645bc3..e25436b 100644 --- a/src/XppLens/XppLens.csproj +++ b/src/XppLens/XppLens.csproj @@ -11,6 +11,8 @@ false true en + + ..\..\packaging\icon\xpplens.ico From 9f7b82047ff44dd82e18fff71493f5a76224dba0 Mon Sep 17 00:00:00 2001 From: WillowDev <216433317+willowdev-code@users.noreply.github.com> Date: Tue, 27 Oct 2026 10:28:33 +0100 Subject: [PATCH 2/3] Ship SQLite next to the EXE instead of extracting it to TEMP; setup renames DLLs in use --- CHANGELOG.md | 6 ++++++ pack.ps1 | 4 +++- packaging/inno/xpp-lens.iss | 38 ++++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc48f86..fb3fbfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ All notable changes to xpp-lens (called xpp-graft up to 1.2.0). Versions follow - Start menu entry `xpp-lens`: a console that shows the command list and takes any `xpplens` command, also right after installing, before Explorer picks up the new PATH. +### Fixed +- `xpplens` failed to start with "Failed to determine default extraction location" when TEMP pointed to a missing + folder (a remote desktop session's `Temp\` after a cleanup), e.g. from the Start menu entries. The SQLite library + now ships next to `xpplens.exe` (`bin\e_sqlite3.dll`) instead of being extracted to TEMP at every start; the setup + program renames it like the running EXE when an open Claude session holds it. + ## 1.3.2 — 2026-10-26 ### Fixed diff --git a/pack.ps1 b/pack.ps1 index c885259..8018142 100644 --- a/pack.ps1 +++ b/pack.ps1 @@ -48,7 +48,9 @@ if ($FrameworkDependent) { $publishArgs += @('--self-contained', 'false') } else { - $publishArgs += @('--self-contained', 'true', '-p:PublishSingleFile=true', '-p:IncludeNativeLibrariesForSelfExtract=true', '-p:EnableCompressionInSingleFile=true') + # Native libraries (SQLite) stay next to the EXE: bundled ones would be extracted to %TEMP% at every start, which + # fails when TEMP points to a missing folder (a remote desktop session's Temp\ after a cleanup). + $publishArgs += @('--self-contained', 'true', '-p:PublishSingleFile=true', '-p:IncludeNativeLibrariesForSelfExtract=false', '-p:EnableCompressionInSingleFile=true') } Write-Host "publishing ($(if ($FrameworkDependent) { 'requires .NET 9' } else { 'self-contained' }))..." -ForegroundColor Cyan diff --git a/packaging/inno/xpp-lens.iss b/packaging/inno/xpp-lens.iss index 1417093..0189e90 100644 --- a/packaging/inno/xpp-lens.iss +++ b/packaging/inno/xpp-lens.iss @@ -325,17 +325,41 @@ begin end; end; -{ A running xpplens.exe (an open Claude session) cannot be overwritten but can be renamed; xpplens removes *.old - files when it starts. Whether this is an update is decided here, before the files are copied. } -function PrepareToInstall(var NeedsRestart: Boolean): String; +{ A running xpplens.exe and the e_sqlite3.dll it loaded (an open Claude session) cannot be overwritten but can be + renamed; xpplens removes *.old files when it starts. Whether this is an update is decided here, before the files + are copied. } +procedure RenameInUse(Pattern: String); var - Exe: String; + Bin, Stamp: String; + Found: TFindRec; + Names: TArrayOfString; + I: Integer; +begin + Bin := ExpandConstant('{app}\bin\'); + Stamp := GetDateTimeString('yyyymmddhhnnss', #0, #0); + { Names first, renames after: renaming while the folder is being listed could list a file twice. } + if FindFirst(Bin + Pattern, Found) then + try + repeat + if (Found.Attributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then + begin + SetArrayLength(Names, GetArrayLength(Names) + 1); + Names[GetArrayLength(Names) - 1] := Found.Name; + end; + until not FindNext(Found); + finally + FindClose(Found); + end; + for I := 0 to GetArrayLength(Names) - 1 do + RenameFile(Bin + Names[I], Bin + Names[I] + '.' + Stamp + '.old'); +end; + +function PrepareToInstall(var NeedsRestart: Boolean): String; begin Result := ''; WasUpdate := FileExists(ExpandConstant('{app}\xpplens.json')); - Exe := ExpandConstant('{app}\bin\xpplens.exe'); - if FileExists(Exe) then - RenameFile(Exe, Exe + '.' + GetDateTimeString('yyyymmddhhnnss', #0, #0) + '.old'); + RenameInUse('*.exe'); + RenameInUse('*.dll'); end; procedure CurStepChanged(CurStep: TSetupStep); From 6badd825900423e61c3e6c9bfeb86b7a9b8be1bd Mon Sep 17 00:00:00 2001 From: WillowDev <216433317+willowdev-code@users.noreply.github.com> Date: Tue, 27 Oct 2026 10:36:53 +0100 Subject: [PATCH 3/3] xpp-lens 1.3.3 ### Added - An icon (a lens over X++ on a violet tile) for `xpplens.exe`, the setup program, the Start menu and Windows' installed apps; drawn by `packaging/icon/make-icon.ps1`. - Start menu entry `xpp-lens`: a console that shows the command list and takes any `xpplens` command, also right after installing, before Explorer picks up the new PATH. ### Fixed - `xpplens` failed to start with "Failed to determine default extraction location" when TEMP pointed to a missing folder (a remote desktop session's `Temp\` after a cleanup), e.g. from the Start menu entries. The SQLite library now ships next to `xpplens.exe` (`bin\e_sqlite3.dll`) instead of being extracted to TEMP at every start; the setup program renames it like the running EXE when an open Claude session holds it. --- src/XppLens/XppLens.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XppLens/XppLens.csproj b/src/XppLens/XppLens.csproj index e25436b..b9aa4ac 100644 --- a/src/XppLens/XppLens.csproj +++ b/src/XppLens/XppLens.csproj @@ -22,7 +22,7 @@ xpp-lens — X++ code index for MCP X++ (Dynamics 365 F&O) code index served to AI assistants over MCP Copyright © 2026 WillowDev - 1.3.2 + 1.3.3