run windows apps in termux but natively no root or proot
Getting a full copy of Adobe Photoshop running on an Android phone sounds like a party trick, but with Hangover (a Wine fork that adds ARM64 support via box64/FEX-emu translation) and a couple of small wrapper scripts, it’s a genuinely usable setup inside Termux. This post walks through what worked, what didn’t, and the scripts I use to keep things sane.
TL;DR results
- Photoshop CC 2020 — runs.
- Photoshop CS2015 — runs just as well as CC 2017.
- Photoshop CC 2017 — runs.
- Everything above is running as x86 (32-bit) only. x64 builds refuse to cooperate.
Why x86 only
Hangover gives you a choice of translation backends for both the x86 and x64 sides of WoW64 (FEX-emu, box64, or the native CPU path), but in practice only the 32-bit Photoshop builds come up cleanly for me. The x64 builds either hang during Adobe’s installer or crash the moment the UI tries to initialize. Rather than fight it, I just standardized on installing the “(32 Bit)” Photoshop variant across every version I tried, which sidesteps the issue entirely.
DXVK dll headaches
Hangover wine repo provide DXVK dlls. You can place them in syswow64 and system32 directories and over ride builtin. But for me they were messing things more even I was using vulkan-mesa-icd-freedeno drivers.
What Wine actually needs
Through trial and error, the winetricks verbs that matter for a working prefix are:
gdipluswin7(Windows version override)corefontsfontsmooth=rgb
Skip any of these and you’ll see missing UI glyphs, broken dialogs, or font rendering that makes panels unreadable.
The vcrun crash trap
Manually installing vcrun2015 and vcrun2019 through winetricks reliably crashed the prefix for me. The fix was to not install them myself at all — the Photoshop installer bundles and installs the VC++ redistributables it needs as part of its own setup routine. Let Adobe’s installer do that work instead of winetricks.
The setup script
Here’s the script I use to wire everything together: it symlinks the wine binary to Hangover’s build, drops in a wineserver shim, fetches winetricks, creates a desktop launcher for Photoshop, and builds two families of wrapper commands (hw* and wt*) so I can switch translation backends per-launch without editing environment variables by hand every time.
#!/data/data/com.termux/files/usr/bin/env sh
echo "creating wine link to hangover-wine"
ln -sf /data/data/com.termux/files/usr/bin/hangover-wine /data/data/com.termux/files/usr/bin/wine
echo "writing wineserver wrapper"
cat << 'EOF' > "$BIN_DIR/wineserver"
#!/data/data/com.termux/files/usr/bin/env sh
exec /data/data/com.termux/files/usr/opt/hangover-wine/bin/wineserver "$@"
EOF
echo "Downloading winetricks"
wget -O "$BIN_DIR/winetricks" \
https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
chmod +x "$BIN_DIR/winetricks"
echo "Creating desktop file"
mkdir -p "$APP_DIR"
cat > "$APP_DIR/photoshop.desktop" << 'EOF'
[Desktop Entry]
Version=1.0
Type=Application
Name=Adobe Photoshop
Comment=Launch Adobe Photoshop via Wine
Exec=env HODLL=libwow64fex.dll wine "C:\\Program Files (x86)\\Adobe\\Adobe Photoshop\\Photoshop.exe"
Icon=photoshop
Categories=Graphics;
Path=
Terminal=false
StartupNotify=false
EOF
cat > "$BIN_DIR/hwrap" << 'EOF'
#!/data/data/com.termux/files/usr/bin/bash
#
cmd="$(basename "$0")"
#
case "$cmd" in
hwfex)
# FEX for both x64 and x86
export HODLL64="libarm64ecfex.dll"
export HODLL="libwow64fex.dll"
;;
hw64fex)
# FEX for x64 only
export HODLL64="libarm64ecfex.dll"
;;
hw32fex)
# FEX for x86 only
export HODLL="libwow64fex.dll"
;;
hwcpu)
# Native WoW64 CPU for x86
export HODLL="wow64cpu.dll"
;;
hwbox)
# Box64-based x86 emulation
export HODLL="wowbox64.dll"
;;
*)
echo "Unknown invocation: $cmd"
echo "Usage examples:"
echo "hwfex for both x64 and x32"
echo "hw64fex for x64 and fex"
echo "hw32fex for x32 and fex"
echo "hwcpu for x32 and native"
echo "hwbox for x32 and box64"
exit 1
;;
esac
exec wine "$@"
EOF
cat > "$BIN_DIR/wtwrap" << 'EOF'
#!/data/data/com.termux/files/usr/bin/bash
export WINE="/data/data/com.termux/files/usr/bin/hangover-wine"
export WINESERVER="/data/data/com.termux/files/usr/opt/hangover-wine/bin/wineserver"
export WINEPREFIX="$HOME/.wine"
#
cmd="$(basename "$0")"
#
case "$cmd" in
wtfex)
# FEX for both x64 and x86
export HODLL64="libarm64ecfex.dll"
export HODLL="libwow64fex.dll"
;;
wt64fex)
# FEX for x64 only
export HODLL64="libarm64ecfex.dll"
;;
wt32fex)
# FEX for x86 only
export HODLL="libwow64fex.dll"
;;
wtcpu)
# Native WoW64 CPU for x86
export HODLL="wow64cpu.dll"
;;
wtbox)
# Box64-based x86 emulation
export HODLL="wowbox64.dll"
;;
*)
echo "Unknown invocation: $cmd"
echo "Usage examples:"
echo "wtfex for both x64 and x32"
echo "wt64fex for x64 and fex"
echo "wt32fex for x32 and fex"
echo "wtcpu for x32 and native"
echo "wtbox for x32 and box64"
exit 1
;;
esac
exec winetricks "$@"
EOF
chmod +x "$BIN_DIR/hwrap"
chmod +x "$BIN_DIR/wtwrap"
echo "Creating links"
ln -sf "$BIN_DIR/hwrap" "$BIN_DIR/hwfex"
ln -sf "$BIN_DIR/hwrap" "$BIN_DIR/hw64fex"
ln -sf "$BIN_DIR/hwrap" "$BIN_DIR/hw32fex"
ln -sf "$BIN_DIR/hwrap" "$BIN_DIR/hwcpu"
ln -sf "$BIN_DIR/hwrap" "$BIN_DIR/hwbox"
ln -sf "$BIN_DIR/wtwrap" "$BIN_DIR/wtfex"
ln -sf "$BIN_DIR/wtwrap" "$BIN_DIR/wt64fex"
ln -sf "$BIN_DIR/wtwrap" "$BIN_DIR/wt32fex"
ln -sf "$BIN_DIR/wtwrap" "$BIN_DIR/wtcpu"
ln -sf "$BIN_DIR/wtwrap" "$BIN_DIR/wtbox"
How the wrappers work
Both wrapper families use $(basename "$0") to figure out which symlink was called, then set the right HODLL/HODLL64 environment variables before handing off to the real binary:
hw*commands (hwfex,hw64fex,hw32fex,hwcpu,hwbox) wrapwinedirectly — use these for actually launching Photoshop with a specific translation backend.wt*commands (wtfex,wt64fex,wt32fex,wtcpu,wtbox) wrapwinetrickswith the same backend choices, plus setWINE,WINESERVER, andWINEPREFIXexplicitly, since winetricks needs those to find the right prefix.
The five backend choices per family:
| Suffix | Backend |
|---|---|
fex |
FEX-emu for both x64 and x86 |
64fex |
FEX-emu for x64 only |
32fex |
FEX-emu for x86 only |
cpu |
Native WoW64 CPU path (x86) |
box |
box64-based emulation (x86) |
Since everything Photoshop-related here is x86-only for me, in practice hw32fex and wt32fex are what I actually reach for day to day; the rest exist mostly so I can quickly A/B test whether a different backend fixes a given crash.
Putting it together
- Run the setup script once to create the symlinks, wrapper commands, and desktop launcher.
- Set up a
WINEPREFIX, then run the font/UI prerequisites through the wrapper:wt32fex corefonts gdiplus win7 fontsmooth=rgb. - Run the Photoshop installer itself through
hw32fex— let it install its own bundled VC++ redistributables rather than pre-installingvcrun2015/vcrun2019separately. - Launch via the
photoshop.desktopentry, or directly withhw32fex "C:\Program Files (x86)\Adobe\...\Photoshop.exe".
That’s the whole recipe. It’s not perfect — not everything works in photoshop while major headache is generator, x64 is a no-go, and you’ll want patience during the Adobe installer — but for basic photo editing on a phone, it’s a surprisingly solid setup given mobile photoshop app is battery hungry and no alignments.
← back