Skip to content

Instantly share code, notes, and snippets.

@aont
Created October 4, 2025 13:33
Show Gist options
  • Select an option

  • Save aont/4240456b8ce671c07984798209f8a911 to your computer and use it in GitHub Desktop.

Select an option

Save aont/4240456b8ce671c07984798209f8a911 to your computer and use it in GitHub Desktop.

Registering a custom URL scheme (e.g. hoge://fuga) — Windows & Linux, user-level steps and caveats

You can absolutely register a custom protocol like hoge:// so that hoge://fuga opens your app. Below is a compact, practical how-to for both Windows and Linux (user-only: no admin required), with ready-to-use examples and short security notes. Copy → paste → test — sanity checks included.


Windows (user-level, no admin)

1) Quick .reg (current user)

Put this in a file named hoge-protocol.reg, double-click to import (HKCU — no UAC):

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\hoge]
@="URL:hoge Protocol"
"URL Protocol"=""

[HKEY_CURRENT_USER\Software\Classes\hoge\shell\open\command]
@="\"C:\\Program Files\\HogeApp\\hoge.exe\" \"%1\""

The %1 receives the full URL (e.g. hoge://fuga). To uninstall, delete the HKCU\Software\Classes\hoge key.

2) How it works (short)

  • Create HKCU\Software\Classes\<scheme> or HKLM\SOFTWARE\Classes\<scheme>.
  • Add a URL Protocol value (can be empty) to mark it as a URL scheme.
  • Put the executable command in shell\open\command default, e.g. "C:\path\app.exe" "%1".
  • HKCU = per-user (no admin). HKLM = machine-wide (admin required). Note registry redirection on 32/64-bit, though HKCU is usually straightforward.

3) PowerShell script (scriptable install)

$scheme = "hoge"
$exe = "C:\Program Files\HogeApp\hoge.exe"
New-Item -Path "HKCU:\Software\Classes\$scheme" -Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\Classes\$scheme" -Name '(Default)' -Value "URL:hoge Protocol"
New-ItemProperty -Path "HKCU:\Software\Classes\$scheme" -Name "URL Protocol" -Value "" -Force | Out-Null
New-Item -Path "HKCU:\Software\Classes\$scheme\shell\open\command" -Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\Classes\$scheme\shell\open\command" -Name '(Default)' -Value "\"$exe\" \"%1\""

4) Test

  • Press Win + R, type hoge://fuga, Enter.
  • CMD: start "" "hoge://fuga"
  • PowerShell: Start-Process "hoge://fuga"

Your app should start and receive the URL as an argument.

5) App side — what to expect & safety

  • Most runtimes get the URL as argv[1] (or equivalent). It may be URL-encoded — decode before use.
  • Strictly validate input. Treat any incoming URL as untrusted: validate scheme, host/path, query params, and avoid handing raw parts to shells, filesystem routines, or webviews without sanitization.
  • Browsers/OS may prompt the user before launching an external app — that’s normal.
  • If distributing widely, prefer installing via an installer that writes HKLM entries (requires admin) so the scheme is system default.

6) UWP / Store / Electron / .NET note

  • UWP apps declare protocols in Package.appxmanifest (<uap:Extension Category="windows.protocol">) — the package system registers them; direct registry edits aren’t the path.
  • Electron offers app.setAsDefaultProtocolClient(); .NET also has APIs. Use platform APIs where available.

7) Remove (PowerShell)

Remove-Item -Path "HKCU:\Software\Classes\hoge" -Recurse -ErrorAction SilentlyContinue

Linux (freedesktop / user-level)

On Linux desktops, register a handler via a .desktop file and x-scheme-handler/<scheme> MIME type.

1) Create a .desktop file (user)

Save as ~/.local/share/applications/hoge.desktop (replace exec path):

[Desktop Entry]
Name=HogeApp
Exec=/home/youruser/bin/hoge-app %u
Terminal=false
Type=Application
Categories=Utility;
MimeType=x-scheme-handler/hoge;

Notes:

  • Use %u (single URL) or %U (multiple) in Exec to receive the URL.
  • For system-wide install, place in /usr/share/applications/ (root required).

2) Update desktop database (optional)

Many environments auto-detect the file. To be sure:

update-desktop-database ~/.local/share/applications || true

(If update-desktop-database is not installed, it’s fine — proceed to next steps.)

3) Set as default for the scheme

Choose the mechanism your desktop uses:

xdg-mime default hoge.desktop x-scheme-handler/hoge
# or (GNOME/glib)
gio mime x-scheme-handler/hoge hoge.desktop
# sometimes (KDE / environment-dependent)
xdg-settings set default-url-scheme-handler hoge hoge.desktop

4) Test

xdg-open 'hoge://fuga'
# or, depending on environment:
gtk-launch hoge

Clicking hoge://… links in a browser should also trigger the app (browser may prompt).

5) App side & caveats

  • The URL is passed to the app via command arguments (e.g. argv[1]), or via D-Bus/activation if a single-instance GUI is already running — implement single-instance handling if desired.
  • Flatpak / Snap: sandboxing may block integration. Flatpak apps often require portal permissions; a simple .desktop may not be sufficient.
  • Desktop environments differ slightly (GNOME, KDE, XFCE), but .desktop + xdg-mime is the most portable approach.

6) Remove

rm ~/.local/share/applications/hoge.desktop
update-desktop-database ~/.local/share/applications || true
# if the default remains, overwrite with xdg-mime to another handler

Security & best practices (quick checklist)

  • Validate everything in the incoming URL (scheme, hostname/path, query params).
  • Do not build shell commands by concatenating URL parts. Escape or avoid shells.
  • Consider whether the app should run non-privileged; prefer HKCU / user-level installs unless you intentionally need machine-wide behavior.
  • When distributing, use an installer that registers the scheme properly and documents the UX (browser prompts, confirmation dialogs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment