11 KiB
Wine on Nix — notes for EQLogParser
This document captures troubleshooting lessons from packaging EQLogParser on Linux with Wine and Nix. It is meant for maintainers and anyone running the app outside Bottles/Flatpak.
For day-to-day usage, see eqlogparser.md. The reference implementation is packages/eqlogparser/package.nix, which mirrors the upstream Bottles manifest.
What EQLogParser needs under Wine
EQLogParser is a .NET 8 WPF Windows app. Under Wine that implies:
| Requirement | Why |
|---|---|
64-bit Wine prefix (WINEARCH=win64) |
Release builds are x64 (bottles/Games/eqlogparser.yml) |
| wine-mono in the prefix | Wine’s mscoree shim; without it you get the interactive “Wine could not find a wine-mono package” dialog |
| .NET Desktop Runtime 8 (x64) | WPF needs the desktop runtime, not plain dotnet-runtime or wine-mono alone |
| GDI D3D renderer | WPF on Wine is unstable with default GL/Vulkan paths; Bottles sets renderer=gdi |
| No DXVK / VKD3D | Bottles explicitly disables them for this app |
| Piper TTS installer (recommended) | Wine x64 cannot use Windows SAPI voices; use EQLogParser-install-pipertts-*.exe |
The app also expects WINELOADER to be set so it disables hardware acceleration (software rendering only). See upstream EQLogParser/App.xaml.cs — this matches Linux known issues.
Choosing a Wine package in nixpkgs
nixpkgs exposes several Wine variants. They are not interchangeable for this project.
| Package | Use for EQLogParser? | Notes |
|---|---|---|
pkgs.wine64 |
No (alone) | Often breaks during wineboot / winetricks (syswow64\rundll32.exe / ntdll.dll errors). Prefix may be half-initialized. |
pkgs.wineWow64Packages.stableFull |
Yes | WOW64 + embedInstallers = true bundles wine-mono and gecko MSIs under share/wine/mono/. This is what the flake uses. |
pkgs.wine (default 32-bit WOW) |
No | Wrong architecture for a win64-only bottle. |
pkgs.wine64Packages.full |
Maybe | Has embedInstallers, but lacks the 32-bit side WOW64 often needs for installers and msiexec. Prefer wineWow64. |
Rule of thumb: match Bottles — 64-bit bottle, Wine runner, no DXVK. On Nix that is wineWow64Packages.stableFull with no DXVK in PATH or WINEDLLOVERRIDES.
wine = pkgs.wineWow64Packages.stableFull;
Verify mono is present:
ls "$(nix-build '<nixpkgs>' -A wineWow64Packages.stableFull --no-out-link)/share/wine/mono/"
# e.g. wine-mono-10.0.0-x86.msi
wine-mono vs .NET Desktop Runtime
These solve different problems. Installing only one leads to confusing errors.
wine-mono
- Ships with Wine when
embedInstallers = true(stableFull,fullvariants). - Installed into the prefix via MSI, e.g.
wine msiexec /i "$WINE_PKG/share/wine/mono/wine-mono-"*.msi /qn - Satisfies Wine’s .NET Framework /
mscoreepath and stops the mono download dialog. - Not a substitute for .NET 8.
.NET 8 Desktop Runtime
- Microsoft installer, same as Bottles dependency
dotnetcoredesktop8
(dotnetcoredesktop8.yml). - For win64 bottles, the x64 installer is enough (Bottles also installs x86; we only install x64).
- Example (version pinned in the package):
windowsdesktop-runtime-8.0.12-win-x64.exe /quiet - Winetricks verb
dotnetdesktop8is equivalent but failed in our tests (see below).
Install order (important)
1. wineboot -u
2. wine-mono MSI (/qn)
3. .NET Desktop Runtime (/quiet)
4. renderer=gdi (registry)
5. EQLogParser installer (/VERYSILENT …)
Installing EQLogParser or the .NET runtime before mono triggers the mono dialog and can leave a broken prefix.
Mapping Bottles settings to Nix/Wine
Bottles (eqlogparser.yml + deps) |
Nix / shell equivalent |
|---|---|
Arch: win64 |
export WINEARCH=win64 |
Runner: Wine, dxvk: false, vkd3d: false |
wineWow64Packages.stableFull; do not add DXVK to the environment |
dotnetcoredesktop8 |
windowsdesktop-runtime-8.0.12-win-x64.exe /quiet |
allfonts |
Copy Nix font packages into drive_c/windows/Fonts, register them, and avoid winetricks allfonts |
renderer=gdi |
wine reg add 'HKCU\Software\Wine\Direct3D' /v renderer /t REG_SZ /d gdi /f |
| Piper TTS installer | EQLogParser-install-pipertts-*.exe with Inno flags |
| (implicit) wine-mono | msiexec on bundled wine-mono-*.msi |
Inno Setup silent flags used successfully:
/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
Prefix location and mutability
Do not use /nix/store as WINEPREFIX during setup
Wine refuses to create a configuration directory when ownership checks fail:
wine: '/nix/store' is not owned by you, refusing to create a configuration directory there
This happens if:
WINEPREFIXpoints at$outbefore copy, orHOMEis unset and defaults under/nix/store.
Build-time prefix in the Nix store: possible in theory (build under $NIX_BUILD_TOP, then cp to $out), but the EQLogParser package uses first-run setup in $XDG_DATA_HOME/eqlogparser/wine instead — simpler and avoids sandbox/fontconfig/XDG issues.
Recommended layout
| Variable | Value |
|---|---|
WINEPREFIX |
$XDG_DATA_HOME/eqlogparser/wine (or ~/.local/share/eqlogparser/wine) |
HOME |
User’s real home (or a writable temp dir during one-off setup) |
WINEARCH |
win64 |
WINELOADER |
Path to wine binary (EQLogParser uses this to detect Wine) |
Reset a bad prefix:
rm -rf ~/.local/share/eqlogparser/wine
nix run .#eqlogparser
Winetricks on Nix
winetricks from nixpkgs works, but several verbs failed in testing even after a healthy wineboot and mono install:
warning: wine cmd.exe /c echo '%AppData%' returned empty string
Affected verbs included allfonts, renderer=gdi, and dotnetdesktop8. The prefix was usable; winetricks’ %AppData% probe was not.
Workarounds:
- GDI renderer: set the registry directly (see table above).
- .NET Desktop Runtime: use Microsoft’s
.exefrom Bottles’ dependency URL, not winetricks. - Fonts: copy Nix font packages into
drive_c/windows/Fonts, register them under the WindowsFontsregistry key, and set Wine font replacements for common Windows UI fonts.
Graphics: GDI, DXVK, and WPF
WPF on Wine is sensitive to the renderer:
- Bottles sets
renderer=gdivia winetricks; we set the same registry value. - Do not enable DXVK/VKD3D for this app (Bottles
dxvk: false,vkd3d: false). - EQLogParser forces software rendering when
WINELOADERis set. Confirm in logs:
RenderMode: SoftwareOnlyunder
…/AppData/Roaming/EQLogParser/logs.
If you see rendering glitches, verify GDI is set:
WINEPREFIX=~/.local/share/eqlogparser/wine wine reg query 'HKCU\Software\Wine\Direct3D' /v renderer
Common errors and fixes
“Wine could not find a wine-mono package”
Cause: Prefix has no mono MSI installed, or wrong Wine package (no embedded MSI).
Fix:
- Use
wineWow64Packages.stableFull. - Install mono before anything else:
wine msiexec /i "$(wine --prefix 2>/dev/null; echo $WINE_PKG)/share/wine/mono/wine-mono-"*.msi /qn - Or use
nix run .#eqlogparserand let package.nix run setup.
failed to start L"C:\\windows\\syswow64\\rundll32.exe": c0000135
Cause: pkgs.wine64 prefix without proper WOW64 support.
Fix: Switch to wineWow64Packages.stableFull and recreate the prefix.
App installs but crashes on start / “.NET not found”
Cause: Desktop Runtime 8 x64 missing (only mono or only ASP.NET runtime installed).
Fix: Install windowsdesktop-runtime-8.0.x-win-x64.exe with /quiet.
wine cmd.exe / %AppData% empty (winetricks)
Cause: Known winetricks + Wine prefix quirk on Nix; not always fatal.
Fix: Avoid winetricks for dotnet/gdi; use direct installers and reg add.
Fontconfig / XDG_RUNTIME_DIR during Nix builds
Cause: Building a Wine prefix inside runCommand without a full graphics/font stack.
Fix: Prefer runtime prefix creation (current package design), or add fontconfig / XDG_RUNTIME_DIR to the builder if you revisit store-time prefixes.
Debugging checklist
- Wine version:
wine --version(from the wrappedPATH). - Prefix arch:
grep '#arch=' "$WINEPREFIX"/*.reg→ expectwin64. - Mono installed:
test -d "$WINEPREFIX/drive_c/windows/mono"or check Add/Remove inwine uninstaller. - .NET 8 desktop:
ls "$WINEPREFIX/drive_c/Program Files/dotnet/shared/Microsoft.WindowsDesktop.App/8.*" - App binary:
test -f "$WINEPREFIX/drive_c/Program Files/EQLogParser/EQLogParser.exe" - EQLogParser log:
$WINEPREFIX/drive_c/users/$USER/AppData/Roaming/EQLogParser/logs - Render mode: log line should show
SoftwareOnlyunder Wine. - Piper TTS: log should mention
piper-ttsif using the piper installer.
Run with more Wine noise:
WINEDEBUG=+pid,+process wine …
Why the package uses first-run setup
We tried baking the prefix into the Nix store at build time. Blockers included:
- Wine refusing
/nix/storepaths for initial config - Fontconfig and
XDG_RUNTIME_DIRin the sandbox - Long, brittle builds that still produced prefixes winetricks could not post-process
Current approach: ship Wine + installers in the store; run eqlogparser-setup-prefix on first launch (and on version bumps). Trade-off: first start takes several minutes; later starts are fast.
Manual reproduction (without Nix)
Equivalent to Bottles + upstream manual install docs:
# Use wine-wow64 from your distro or nix shell wineWow64Packages.stableFull
export WINEARCH=win64
export WINEPREFIX="$HOME/.local/share/eqlogparser/wine"
export PATH="/path/to/wine-wow64/bin:$PATH"
wineboot -u
wine msiexec /i /path/to/wine-mono-*.msi /qn
wine windowsdesktop-runtime-8.0.12-win-x64.exe /quiet
wine reg add 'HKCU\Software\Wine\Direct3D' /v renderer /t REG_SZ /d gdi /f
wine EQLogParser-install-pipertts-2.3.54.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
export WINELOADER="$(command -v wine)"
wine "$WINEPREFIX/drive_c/Program Files/EQLogParser/EQLogParser.exe"