Skip to content

Comments

feat: add portable mode to NSIS installer#807

Open
back1ply wants to merge 11 commits intocjpais:mainfrom
back1ply:feat/nsis-portable-installer
Open

feat: add portable mode to NSIS installer#807
back1ply wants to merge 11 commits intocjpais:mainfrom
back1ply:feat/nsis-portable-installer

Conversation

@back1ply
Copy link
Contributor

@back1ply back1ply commented Feb 12, 2026

Before Submitting This PR

Please confirm you have done the following:

If this is a feature or change that was previously closed/rejected:

  • I have explained in the description below why this should be reconsidered
  • I have gathered community feedback (link to discussion below)

Human Written Description

Welp, lets hope 2nd time a charm :)
Anyway, a test nsis (exe) file is available, any volunteers with a windows machine are welcome to test.
https://github.com/back1ply/Handy/actions/runs/21954326041/artifacts/5485647980

The Portable option in the setup
image

Related Issues/Discussions

Fixes #153
Supersedes the reverted #753 with a fundamentally different approach.
See also: #567, #785

Previous approach (#753) added a ZIP-based portable distribution but was reverted because:

  1. App data still went to %APPDATA% — not truly portable (as noted by @jsntn and @JoeBarouneD in feat: add portable ZIP archives for Windows releases #753 comments)
  2. It added CI complexity for something that didn't fully work

Community Feedback

This PR addresses both concerns directly.

What Changed

Approach: Custom NSIS Template + Runtime Path Redirection

Instead of a separate ZIP distribution, this adds a portable mode option directly in the existing NSIS installer (like Notepad++ does). Users pick "Normal" or "Portable" during install.

Two components:

  1. Custom NSIS template (src-tauri/nsis/installer.nsi) — Based on upstream tauri-v2.9.1 template with 6 targeted modifications:

    • Install type selection page (Normal vs Portable radio buttons)
    • /PORTABLE CLI flag for silent installs
    • Conditional default directory (Desktop\Handy for portable)
    • Skips registry, file associations, shortcuts, and uninstaller for portable
    • Creates portable marker file + Data/ directory
    • Auto-detects existing marker file during updates (so the Tauri updater preserves portable mode)
  2. Runtime path redirection (src-tauri/src/portable.rs) — On startup, detects the portable marker file and redirects ALL data paths (settings, models, recordings, logs, WebView2 cache) to Data/ next to the exe. Nothing touches %APPDATA% or %LOCALAPPDATA%.

Files Changed

File Change
src-tauri/nsis/installer.nsi New — custom NSIS template with portable mode
src-tauri/tauri.conf.json Add nsis.template path
src-tauri/src/portable.rs New — runtime portable detection + path redirection
src-tauri/src/lib.rs Call portable::init() at startup, use portable-aware paths
src-tauri/src/settings.rs Use portable-aware store path
src-tauri/Cargo.toml Add dirs crate for fallback data dir resolution

Usage

GUI install:
Run installer → select "Portable Installation" → choose directory → done

Silent install:

Handy_setup.exe /S /PORTABLE /D=C:\MyFolder\Handy

Updates: The updater automatically detects the portable marker file — no special flags needed.

Maintenance Note

The custom NSIS template must be manually synced when upgrading Tauri. Portable changes are isolated and marked with ; --- PORTABLE MODE --- comments to make merging straightforward. A version comment header notes the base version (tauri-v2.9.1).

Testing

Tested on Windows 10 Pro (x64):

  • Normal install (GUI): registry entries, Start Menu shortcut, uninstaller — all work as before
  • Portable install (GUI): NO registry, NO shortcuts, NO uninstaller. portable marker + Data/ directory created
  • Silent portable: Handy_setup.exe /S /PORTABLE /D=C:\path works
  • App data isolation: in portable mode, all data goes to Data/ — no %APPDATA%\com.pais.handy or %LOCALAPPDATA%\com.pais.handy created
  • CI build: passes on windows-latest with NSIS bundling

Screenshots/Videos (if applicable)

AI Assistance

  • AI was used (please describe below)

If AI was used:

  • Tools used: Claude Code (Claude Opus 4.6)
  • How extensively: AI wrote the NSIS template modifications, portable.rs, and PR description. Human directed the approach, tested all installer modes on Windows, and verified data isolation.

back1ply and others added 10 commits February 9, 2026 15:05
Custom NSIS template based on tauri-v2.9.1 upstream with 6 targeted
modifications for portable mode support:

- New PortableMode variable and /PORTABLE CLI flag for silent installs
- Install type selection page with Normal/Portable radio buttons
- Conditional default directory (Desktop for portable, LocalAppData for normal)
- Skip registry writes, file associations, deep links, and uninstaller for portable
- Skip Start Menu and desktop shortcuts for portable installs
- Create portable marker file and Data/ directory on portable install

The existing portable.rs runtime detection is unchanged — it looks for the
same marker file this installer creates.

Usage:
  GUI: select "Portable Installation" on the install type page
  Silent: Handy_setup.exe /S /PORTABLE /D=C:\path\to\Handy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Detect a `portable` marker file next to the executable at startup.
When present, redirect all data paths (settings, models, recordings,
database, logs) to a local `Data/` directory instead of %APPDATA%.

This approach works because it intercepts path resolution at the Rust
level, bypassing Tauri/Windows Shell API limitations that made the
previous environment-variable and junction approaches unreliable.

Changes:
- Add src-tauri/src/portable.rs with OnceLock-based detection
- Replace all app.path().app_data_dir() calls with portable helper
- Configure tauri-plugin-log to use Folder target when portable
- Configure tauri-plugin-store with absolute path when portable
- Simplify build.yml portable ZIP (exe + resources + marker file)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The .path() method on AppHandle requires `tauri::Manager` in scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move main window creation from tauri.conf.json to setup closure so
we can set data_directory when in portable mode. This prevents
WebView2 from creating %LOCALAPPDATA%\com.pais.handy.

Also set data_directory on the recording overlay window.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the Tauri updater runs the installer with /UPDATE, the install type
page is skipped and /PORTABLE is not passed. Detect the existing portable
marker file in .onInit so updates preserve portable mode automatically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jsntn
Copy link

jsntn commented Feb 13, 2026

Hello @back1ply
Thank you so much for the update! It works for me.

Just one thing — on my Windows 11, after the initial pop-up window for selecting and downloading the model appears and once the download has finished, it hangs for a moment. I assume this is because the application is performing some process maybe decompression?

@JoeBarouneD
Copy link

It's also working for me, great job !

@cjpais
Copy link
Owner

cjpais commented Feb 16, 2026

Thanks for this, this looks much more reasonable for portability. Also great to have other users confirmation, I will see about merging this soon

@github-actions
Copy link

🧪 Test Build Ready

Build artifacts for PR #807 are available for testing.

Download artifacts from workflow run

Artifacts expire after 30 days.

@jsntn
Copy link

jsntn commented Feb 17, 2026

Thanks for this, this looks much more reasonable for portability. Also great to have other users confirmation, I will see about merging this soon

Hi @cjpais

There should be an option of "Portable Installation" in the NSIS executable binary,

image

But it seems to be missing from the latest Handy_0.7.6_x64-setup.exe.

@cjpais
Copy link
Owner

cjpais commented Feb 17, 2026

This PR is not merged. Try the test build in this thread. 0.7.6 does not have portable functionality. I need confirmation that BOTH portable and regular installations from the test build work as expected on Windows.

@jsntn
Copy link

jsntn commented Feb 17, 2026

I see, thank you very much!
Will let you know if any issue on the portable installation.

@cjpais
Copy link
Owner

cjpais commented Feb 19, 2026

@jsntn @JoeBarouneD @back1ply can you try the build here and let me know if it works in both portable and regular installation modes

Download artifacts from workflow run

@back1ply
Copy link
Contributor Author

back1ply commented Feb 19, 2026

Notes for the NSIS for now:
The App works in both modes (normal and portable), the only thing that was unexpected, that the app update while in portable mode, it downloads and install the msi version of the app. (this happens also in normal install mode as well)

I expect for the install mode and update path to be
MSI install -> MSI update
NSIS normal install -> NSIS normal update
NSIS portable install -> NSIS portable update

I am not sure yet how we can do the NSIS portable update but as a compromise for if we detect a portable install the update button will show a pop up asking user to manally download the nsis from github and copy his old files (recordings, settings and models) from old vers. to new one.

Also in portable mode, the "Create Desktop Shortcut" seems to be not working.

@jsntn
Copy link

jsntn commented Feb 19, 2026

@jsntn @JoeBarouneD @back1ply can you try the build here and let me know if it works in both portable and regular installation modes

Download artifacts from workflow run

Hi @cjpais
I tried the portable installation, it works and I don't find issue for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ZIP release (Windows).

4 participants