English | Русский
Run Razer Axon on Linux through Wine — with login support, taskbar fixes and wallpaper decryption. Includes a native GTK4 client and full reverse-engineering documentation of the Razer Axon protocols.
| File | Description |
|---|---|
scripts/установить-axon.sh |
One-command install: prefix, .NET, Razer Central, Axon, WebView2, rendering, launcher |
razer-login.py |
Razer ID login |
razer-token-inject.py |
Injects the token into Razer Central Service (works without patching the DLL) |
razer-token-refresh.sh |
Silent token auto-refresh (for a systemd --user timer, see systemd/) |
razer-axon-gui.py |
Native GTK4/Adwaita client for Linux |
openaxon-player.py |
Native wallpaper daemon (video/static, multi-monitor, effects) |
razer-axon.sh |
Launches the original Axon through Wine |
razer-axon-decrypt.py |
Extracts encrypted video wallpapers |
razer-sync.py |
Syncs wallpapers with your Razer account |
patch/RazerAxon.UserManager.dll |
Patched DLL (legacy method, see below) |
Full documentation of the Razer Axon protocols, extracted from 27 .NET DLLs and JS bundles:
| Document | Description |
|---|---|
docs/razer-central-ipc.md |
Razer Central IPC protocol — 4 services, 137+ commands, wire format |
docs/axon-api.md |
REST API — ~110 endpoints, HMAC authentication, download manager |
docs/react-architecture.md |
React 18 frontend — 24 routes, state management, WebView2 bridge |
docs/wallpaper-player.md |
Player pipe protocol — JSON commands, effects, multi-monitor |
docs/chroma-sdk.md |
Chroma RGB — REST API, .chroma format, AI generation, LED maps |
docs/design-system.md |
CSS design system — colors, fonts, 13 component groups |
docs/webview-host-objects.md |
JS↔C# bridge — 6 host objects, 111 methods |
docs/utilities.md |
Logger, Environment, Notifications, Telemetry |
docs/reporter-screensaver.md |
Analytics reporter and screensaver launcher |
- Wine (tested with Wine 9.x / 10.x; the full Axon 2.9.1.0 install — on Wine 11.15)
- Python 3.10+
- PyGObject with GTK4, libadwaita and WebKit2
- xdotool, xprop (for the taskbar fix on X11)
- 7z or unzip (for wallpaper decryption)
- mpvpaper — video wallpapers on Wayland
- xwinwrap + mpv — video wallpapers on X11
- feh — setting static wallpapers (fallback)
sudo pacman -S wine python-gobject gtk4 libadwaita webkit2gtk-4.1 xdotool xorg-xprop p7zipsudo apt install wine python3-gi gir1.2-gtk-4.0 gir1.2-adw-1 gir1.2-webkit2-4.1 xdotool x11-utils p7zip-fullsudo dnf install wine python3-gobject gtk4 libadwaita webkit2gtk4.1 xdotool xprop p7zipsudo zypper install wine python3-gobject gtk4 libadwaita webkit2gtk3-soup2-devel xdotool xprop p7zipsudo xbps-install wine python3-gobject gtk4 libadwaita webkit2gtk41 xdotool xprop p7zipsudo emerge app-emulation/wine dev-python/pygobject gui-libs/gtk:4 gui-libs/libadwaita net-libs/webkit-gtk x11-misc/xdotool x11-apps/xprop app-arch/p7zip# configuration.nix or home-manager
environment.systemPackages = with pkgs; [
wineWowPackages.stable
python3
python3Packages.pygobject3
gtk4
libadwaita
webkitgtk_4_1
xdotool
xorg.xprop
p7zip
];./scripts/установить-axon.shThe script is non-interactive: it creates a dedicated Wine prefix, installs .NET Framework 4.8,
Razer Central, Razer Axon itself and the WebView2 UI engine, configures rendering,
creates a razer-axon command and a "Razer Axon" entry in the application menu, and at the end
checks ten signs that everything is in place. It takes 25-40 minutes and downloads about 1 GB.
An interrupted run can be restarted — completed steps are skipped.
On first launch a Razer Central window opens. No Razer account is needed — just click "Continue as guest", and the full wallpaper catalog opens.
A breakdown of every step and the measurements behind it (in Russian) is in
docs/установка_под_wine_2_9_1_0.md.
export WINEPREFIX="$HOME/.local/share/openaxon/prefix"
WINEARCH=win64 wineboot --init # fresh prefix: already win10, build 19045
winetricks -q dotnet48 # MUST come before Axon (see below)
wine winecfg -v win10 # dotnet48 leaves build 7601 behind
wine RazerCentral_v7.23.0.1220.exe /silent # installs silently only with real .NET
wine RazerAxonSetup_2.9.1.0.exe /SP- /VERYSILENT \
'/DIR=C:\Program Files (x86)\Razer\Razer Axon' /SUPPRESSMSGBOXES /NORESTARTThree places where it's easy to go wrong:
dotnet48before Axon. The Axon installer leaves a never-endingMicrosoftEdgeUpdate.exe /cin the prefix, andwinetrickswaits forwineserver -wat every step — that is, for all processes in the prefix to exit. After Axon, any winetricks verb hangs forever.winecfg -v win10afterdotnet48: it switches the Windows version to 7, and the Axon Inno installer refuses to run on Windows 7 (MinVersion).- the message-box suppression switch is
/SUPPRESSMSGBOXES, with twops. Razer made a typo in its manifest (/SUPRESSMSGBOXES), and Inno silently ignores that switch.
You don't need to register it manually — the Razer Central installer creates it itself,
under the name RzActionSvc (not RazerCentralService, as was wrongly stated here
before):
wine sc query RzActionSvc # → STATE : 4 RUNNINGwineserver. So it has to be started
in the same session in which Axon is launched — which is exactly what the razer-axon
command created by the script does:
wineserver -p # keep the session open
wine sc start RzActionSvc
wine RazerAxon.exe -showuicp razer-axon.sh razer-login.py razer-token-inject.py razer-axon-decrypt.py ~/.local/bin/
chmod +x ~/.local/bin/razer-axon.sh ~/.local/bin/razer-login.py ~/.local/bin/razer-token-inject.py ~/.local/bin/razer-axon-decrypt.py# Get a token
razer-login.py
# Inject it into Razer Central Service
razer-token-inject.pyrazer-login.py opens a WebKit window with the Razer ID login page. After you log in, the script intercepts the JWT token and saves it.
razer-token-inject.py passes the token to Razer Central Service over named pipe IPC. On first run it automatically builds a .NET helper (requires the dotnet SDK 6.0+).
razer-axon.shNote: You can also log in directly through the Axon UI — click "Log in" in the app window. The token injector is only needed if direct login doesn't work.
If the Razer Central Service method doesn't work, you can replace RazerAxon.UserManager.dll with a patched version:
AXON_DIR="$WINEPREFIX/drive_c/Program Files (x86)/Razer/Razer Axon"
cp "$AXON_DIR/RazerAxon.UserManager.dll" "$AXON_DIR/RazerAxon.UserManager.dll.orig"
cp patch/RazerAxon.UserManager.dll "$AXON_DIR/"This method removes the dependency on Razer Central, but has to be reapplied after every Axon update.
razer-login.py # Open the login window
razer-login.py --status # Check the current token's status
razer-token-inject.py # Inject the token into the service
razer-token-inject.py --status # Check the stateTokens expire after about 24 hours. You can refresh manually (razer-login.py), but it's more convenient to set up auto-refresh (below).
razer-login.py --refresh silently gets a new token using the saved Razer ID session
cookies — without a login window — and only when the token expires within the hour
(otherwise it's a quick no-op). As long as the Razer ID session is alive, you don't need to
enter your login/password again.
razer-token-refresh.sh wraps this: it calls --refresh and syncs the fresh
token into the Wine prefix (where the RazerAxon.UserManager.dll patch reads
wine_login_token.json from). Put it on a systemd --user timer (every 30 min):
# The units in systemd/ point to %h/Projects/openaxon/razer-token-refresh.sh —
# adjust ExecStart to your path if the repository lives elsewhere.
cp systemd/razer-axon-token-refresh.{service,timer} ~/.config/systemd/user/
systemctl --user daemon-reload
# WebKit needs access to the graphical session for silent refresh:
systemctl --user import-environment WAYLAND_DISPLAY DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS XDG_RUNTIME_DIR
systemctl --user enable --now razer-axon-token-refresh.timerWhen the session cookies eventually expire (weeks), the timer logs an error — then
log in interactively once (razer-login.py).
razer-axon.sh # Launch Razer AxonThe launch script:
- Sets Wine environment variables for WebView2 compatibility
- If Axon is already running, activates the existing window
Reactively fixes taskbar visibility (removes— the workaround is obsolete and has been removed: on wine 11.15 with Plasma 6.7.4, removing the property does not bring back the taskbar entry (measured, run 17)WM_TRANSIENT_FOR)
The Razer Axon UI is rendered by an embedded WebView2 (msedgewebview2 / Chromium).
Under Wine, Chromium's GPU/Viz process crashes on CHECK()/__debugbreak() during
GPU init (exit code 0x80000003 = STATUS_BREAKPOINT) and restarts in a loop;
once the GPU crash limit is exhausted (~3-6 crashes in a row), the browser process
exits deliberately → Axon sees CoreWebView2ProcessFailed / reason
BrowserProcessExited and closes the UI window. The main Axon process
survives. This is NOT Mojo IPC and NOT authentication (the earlier hypothesis was disproven,
see below).
Fix (the main lever) — Windows 7 for the renderer, to bypass DirectComposition:
razer-axon.sh and install-axon-linux.sh idempotently set in the prefix registry:
Version=win7formsedgewebview2.exeinHKCU\Software\Wine\AppDefaults— the key part. With a Windows version ≥8.1, Chromium's viz presents the frame (even a software bitmap) through DirectComposition (DCompositionCreateDevice), which Wine doesn't implement (E_NOTIMPL/0x80004001) → CHECK → viz crash → the frame never reaches the window = black screen. Underwin7the sameSoftwareOutputDevicegoes through GDI BitBlt (no DComp) and actually copies the pixels into the window;HardwareAccelerationModeEnabled=0inHKLM/HKCU\Software\Policies\Microsoft\Edgeand...\Edge\WebView2— auxiliary (Edge doesn't start a HW GPU process).
Important — two DIFFERENT Windows-version levers:
win7is set ONLY for the renderer subprocessmsedgewebview2.exe;RazerAxon.exeand the prefix globally stay onwin10— otherwise the Razer server returns an empty catalog (login/content don't work). Seeset_win10in the installer.Sources for the fix: WineHQ Bug 58921, winetricks #2226, CodeWeavers, Arch Forums.
Additional mitigations applied by razer-axon.sh:
- Evergreen runtime (default). Axon renders home through the bundled
evergreen WebView2 (Chromium 149) — the only configuration in which
CreateCoreWebView2Environmentinitializes under Wine. Fixed-version (INSTALL_WV2_FIXED=1) is not recommended (see below). - Software-only rendering.
LIBGL_ALWAYS_SOFTWARE=1,GALLIUM_DRIVER=llvmpipe, Mesa EGL — remove NVIDIA EGL noise under XWayland. - Chromium flags (
WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS):--no-sandbox --disable-gpu --disable-gpu-compositing --disable-software-rasterizer --disable-gpu-sandbox --disable-features=RendererCodeIntegrity --disable-crash-reporter --disable-renderer-backgrounding --disable-background-timer-throttling.
Status (2026-06-12): verified live on Wine 11.10 + RTX 4070 (Wayland). The root cause was re-established from Chromium's stderr (
gpu_process_host.cc:1063 GPU process exited unexpectedly: exit_code=-2147483645=0x80000003, "has crashed N time(s)"). A single baseline run recorded 12 gpu-process spawns.Before the fix (baseline): the GPU process crashes ~6 times →
BrowserProcessExitedafter ~10-17 s, the cycle repeats ~38 times in 200 s (the UI flickers).After the fix (
win7for msedgewebview2.exe + win10 for the app): the Axon UI actually renders — confirmed visually (the home page with the banner carousel/TRENDING and the Razer ID Login screen rendered fully, 2026-06-18). The black screen is gone: viz no longer callsDCompositionCreateDevice, presentation goes through GDI BitBlt. The--disable-gpu-process-crash-limitflag has been removed underwin7as redundant (the DComp crash loop is fixed at the root; the flag only masked the symptom) — verified live, the UI renders without it.Background: the registry used to set
win81by mistake (= the threshold at which DComp is enabled) — this got rid ofBrowserProcessExited(white screen), but viz looped on the DComp crash and produced no frames → a black screen. Switching towin7is the real fix.WineHQ #56378 is NOT about named pipes/Mojo (research, Anubis workaround): it's a Chromium sandbox bring-up bug, closed FIXED in Wine 11.1; its companion #56377 (freeze) was FIXED in 10.5. All their fixes (winstation/desktop/token,
DeriveCapabilitySidsFromName,SetAdditionalForegroundBoostProcesses) are already present in the system Wine 11.10. Chromium Mojo uses named pipes in BYTE mode (long supported by Wine); since Chrome ~112, Mojo has moved to shared memory (ipcz). → A Wine named-pipe patch is not needed and wouldn't help; no patched Wine was built (cancelled based on the research).What did NOT help before (verified live):
--single-process(crashes faster),--no-zygote, disablingwerfault.exe, Xvfb without NVIDIA EGL (EGL is not the root cause),--disable-watchdog/--disable-hang-monitor, the fixed-version runtime 109/133 (the version doesn't bring stability). To get rid of the remaining single early crash:--disable-gpu-watchdog+ a higher GPU crash limit, Wine-Staging ≥11.6 (DirectComposition patchset), or moving WebView2 into an external host (CDP proxy).
Razer Axon stores downloaded wallpapers as ZipCrypto-encrypted ZIP archives disguised as .mp4.
# Auto-scan and extract all wallpapers
razer-axon-decrypt.py
# Show passwords only
razer-axon-decrypt.py -p
# Dry run (no extraction)
razer-axon-decrypt.py -n
# Skip already extracted
razer-axon-decrypt.py -s
# Custom directories
razer-axon-decrypt.py -d /path/to/wallpapers -o /path/to/output
# A single file
razer-axon-decrypt.py -f wallpaper.mp4 -c ResourceConfig.txt
# JSON output (for automation)
razer-axon-decrypt.py -j
# English interface
razer-axon-decrypt.py --lang en
# Verbose output (debug)
razer-axon-decrypt.py -vEach wallpaper's password is derived from its ResourceConfig.txt:
import hmac, hashlib
content = open("ResourceConfig.txt").read()
password = hmac.new(b"j6l-aUmhCc@tN%T_", content.encode(), hashlib.sha256).hexdigest()The HMAC key is hardcoded in the Razer Axon .NET assemblies.
┌─────────────────────────────────────────────────────┐
│ Razer Axon (Wine) — original files, no patches │
│ │
│ RazerAxon.exe │
│ │ │
│ ├── RazerAxon.UserManager.dll (ORIGINAL) │
│ │ └── NacClient ──► named pipe IPC │
│ │ │
│ ├── WebView2 UI ──► axon-api.razer.com │
│ │ │
│ └── WallpaperPlayerManager │
│ └── ZIP decryption → playback │
│ │
│ RazerCentralService.exe (Wine service) │
│ ├── AccountManager ──► authentication │
│ ├── Named pipe IPC ──► link to Axon │
│ └── Razer API ──► manifest.razerapi.com │
│ │
├─────────────────────────────────────────────────────┤
│ Linux │
│ │
│ razer-login.py ──► id.razer.com ──► JWT token │
│ razer-token-inject.py ──► pipe IPC ──► service │
│ razer-axon.sh ──► Wine + environment/taskbar fixes │
│ razer-axon-decrypt.py ──► HMAC-SHA256 → unzip │
│ │
└─────────────────────────────────────────────────────┘
Razer Central Service (RazerCentralService.exe) runs as a Wine service and listens on the named pipe {FC828A97-C116-453D-BD88-AD471496E03C}. Axon connects to it through NacClient.dll to obtain the authentication token.
razer-token-inject.py connects to the same pipe and sends the WebApp_SetLoginSuccessFromWeb command with the JWT token obtained via razer-login.py. This emulates web login through the Razer Central GUI (which doesn't display under Wine due to WPF rendering limitations).
All Razer files stay original — no binary patches.
~/.wine/drive_c/users/<USER>/AppData/Local/Razer/RazerAxon/wine_login_token.json:
{
"convertFromGuest": false,
"token": "eyJhbGciOiJFUzI1NiI...",
"isOnline": true,
"isGuest": false,
"uuid": "RZR_...",
"loginId": "user@example.com",
"tokenExpiry": "2026-04-01T21:46:43.000Z",
"stayLoggedIn": true
}Wallpapers in ~/RazerAxonWallpapers/<id>/Resource/ are ZipCrypto-encrypted ZIP archives:
password = HMAC-SHA256("j6l-aUmhCc@tN%T_", ResourceConfig.txt).hexdigest()
The token wasn't injected or has expired:
razer-login.py # Refresh the token
razer-token-inject.py # Inject itThe service is registered by the Razer installer under the name RzActionSvc
(the name RazerCentralService doesn't exist — sc will reply "service not found" for it):
# Check the state
wine sc query RzActionSvc # expect STATE : 4 RUNNING
# Start it manually. wineserver -p is required: the service lives exactly as long
# as the Wine session does, and without it shuts down after a few seconds.
wineserver -p
wine sc start RzActionSvcIf Axon starts but there's no window at all, this is almost always the reason:
RazerAxon.exe doesn't create a window until login through Razer Central has completed.
wine reg add "HKCU\Software\Wine\Fonts\Replacements" /v "Segoe UI" /t REG_SZ /d "Tahoma" /frazer-login.py --status # Check
razer-login.py # Refresh
razer-token-inject.py # Inject againThe launch script fixes this automatically. If the problem persists, make sure xdotool and xprop are installed.
Make sure 7z or unzip is installed and supports ZipCrypto.
Contributions are accepted under the Contributor License Agreement. See CONTRIBUTING.md for how to propose a change.
Apache-2.0 — see LICENSE. Some files are third-party and are not covered by it (the patched Razer DLL and its reconstructed source, the Axon icon) — see NOTICE.