Skip to content

ajsb85/rive-peek

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RivePeek — Rive (.riv) preview handler for Windows Explorer

platform language graphics license release

RivePeek is a native Windows Shell preview handler that renders animated Rive .riv files live in the File Explorer preview pane — the same mechanism Windows uses to preview PDFs, Office documents and images.

Select a .riv file with the preview pane open (Alt + P) and the default artboard plays, fit and centered, isolated inside Windows' prevhost.exe surrogate process so a malformed file can never destabilize Explorer.

It also registers an IThumbnailProvider, so .riv files show a static first-frame thumbnail as their icon in the Explorer file grid.

File Explorer showing .riv files with first-frame thumbnails in the grid and an animated Rive character playing in the preview pane.

RivePeek in File Explorer — static .riv thumbnails in the grid and a live, animated preview pane.

Headless render (rivshot) Live preview pane (captured from the real COM handler)
coin preview pane

Validated against 887 marketplace .riv files: 886 render successfully (99.9%). The single outlier is rejected as malformed by the Rive runtime itself during import.


Features

  • 🎬 Animated preview pane — the default artboard's state machine (or first animation) plays live while the file is selected.
  • 🖼️ Static thumbnails — first-frame .riv thumbnails as grid icons via IThumbnailProvider.
  • 🔤 Text renderingWITH_RIVE_TEXT enabled, shaping via HarfBuzz + SheenBidi (statically linked); text runs draw with the Direct2D backend.
  • 📐 Flexbox layoutWITH_RIVE_LAYOUT enabled, backed by Yoga, so layout-driven artboards and responsive components position correctly.
  • 🛡️ Process-isolated + fault-guarded — runs in Windows' prevhost.exe surrogate, and load/advance/draw/teardown are wrapped in SEH so even a pathological file degrades to a blank preview instead of crashing the host.
  • 💤 Idles when backgrounded — animation pauses when the host/preview isn't in the foreground, and resizes never steal focus from Explorer's file list.
  • 🪶 Self-contained — the core Rive runtime plus HarfBuzz/SheenBidi are compiled in; rendering is pure Direct2D + WIC. RivePeek.dll links the static CRT and needs no redistributables.
  • 🔒 Per-user install — registers under HKCU; no administrator rights.
  • 🧪 Headless toolingrivshot renders any .riv to PNG and validates a whole corpus.

How it works

Windows previews files through COM components hosted out-of-process. When you select a .riv file:

  1. Explorer reads HKCR\.riv\ShellEx\{8895b1c6-…} to find the preview handler's CLSID.
  2. The handler's AppID points at the prevhost.exe surrogate, so Windows loads RivePeek.dll into that isolated host — not into explorer.exe.
  3. Explorer hands the file to the handler as a read-only IStream (IInitializeWithStream), then gives it an HWND + bounding rectangle (IPreviewHandler::SetWindow) and calls DoPreview().
  4. RivePeek parses the file with the Rive C++ runtime, then draws every frame with a Direct2D renderer into a child window, advancing the default state machine (or first animation) on a ~30 fps timer.

Pipeline: explorer.exe hands foo.riv to RivePeek inside the isolated prevhost.exe surrogate via CoCreateInstance, IInitializeWithStream::Initialize and IPreviewHandler::SetWindow/DoPreview; RivePeek imports the file with the Rive C++ runtime and renders it with a Direct2D renderer into an ID2D1HwndRenderTarget.

The Direct2D backend

Rather than compiling Rive's heavyweight GPU "Rive Renderer" (and its shader dependency chain), RivePeek implements Rive's two abstract embedding interfaces directly on top of Direct2D + WIC:

  • rive::FactoryD2DFactory: builds paths (ID2D1PathGeometry), solid/linear/radial brushes, and decodes images via WIC.
  • rive::RendererD2DRenderer: maps save/restore, transform, clipPath (geometry-mask layers), drawPath (fill/stroke), drawImage, and drawImageMesh (per-triangle affine-textured fills) onto an ID2D1RenderTarget. Non-srcOver blend modes are composited with the Direct2D Blend effect (via ID2D1DeviceContext).

The same backend powers a WIC bitmap render target for headless thumbnail generation (no GPU or window required), which doubles as the test harness.

The core Rive runtime is compiled with text (WITH_RIVE_TEXT, linking HarfBuzz + SheenBidi) and layout (WITH_RIVE_LAYOUT, linking Yoga) enabled; audio and scripting stay #ifdef-guarded off (see Limitations).


Repository layout

src/
  guids.hpp           CLSID + registration constants
  rive_d2d.hpp/.cpp   Direct2D implementation of rive::Factory + rive::Renderer
  rive_scene.hpp/.cpp loads a .riv, instantiates artboard + state machine, draws
  preview_handler.*   the COM handler (IPreviewHandler, IInitializeWithStream,
                      IOleWindow, IObjectWithSite, IPreviewHandlerVisuals,
                      IThumbnailProvider)
  dllmain.cpp         COM class factory, DLL exports, (un)registration
  rivepeek.def        exported entry points
tools/
  rivshot.cpp         headless .riv → .png renderer / validation harness
  preview_test.cpp    in-process integration test of the full COM pipeline
  surrogate_test.cpp  out-of-process (prevhost.exe) activation test
  thumb_test.cpp      IThumbnailProvider test (.riv → thumbnail .png)
build/                MSVC build scripts (no CMake required)
install/              register.ps1 / unregister.ps1 / RivePeek.reg
rive-runtime/         Rive C++ runtime (git submodule)
third_party/          HarfBuzz + SheenBidi (text) and Yoga (layout), gitignored
                      (see get_text_deps.bat / get_yoga.bat)

Quick start (prebuilt)

  1. Download RivePeek.dll (and the install scripts) from the latest release.
  2. Put RivePeek.dll somewhere stable, e.g. %LOCALAPPDATA%\RivePeek\.
  3. Register it (per-user, no admin):
    .\install\register.ps1 -Dll "$env:LOCALAPPDATA\RivePeek\RivePeek.dll"
  4. In Explorer, press Alt + P for the preview pane and select a .riv file.

Prefer to build from source? See below.


Building

Requirements: Visual Studio 2022 Build Tools (MSVC v143) and the Windows 10/11 SDK. No CMake needed — the build scripts configure the toolchain themselves.

git clone --recurse-submodules https://github.com/ajsb85/rive-peek.git
cd rive-peek
build\build_all.bat

build_all.bat first runs get_text_deps.bat and get_yoga.bat, which clone the dependencies into third_party/ (~160 MB) — needs git and network access on the first build. They are pinned to the revisions Rive uses (rive-app/harfbuzz @ rive_13.1.1, Tehreer/SheenBidi @ v2.6, rive-app/yoga @ rive_changes_v2_0_1_2) and are compiled into text_deps.lib and yoga.lib. Yoga must be Rive's fork, not upstream — the runtime stores YGNode by value, which upstream made opaque.

This produces, in build\bin\:

Artifact Purpose
RivePeek.dll the preview + thumbnail handler (register to install)
rivshot.exe rivshot in.riv out.png [size] [seconds] — headless render
preview_test.exe drives the COM pipeline in-process and screenshots it
surrogate_test.exe activates the handler in prevhost.exe (like Explorer)
thumb_test.exe renders the IThumbnailProvider thumbnail to a PNG

Individual steps: get_text_deps.bat / get_yoga.bat (clone deps), build_text_deps.bat (text_deps.lib), build_yoga.bat (yoga.lib), build_rive_core.bat (the rive_core.lib static lib), build_dll.bat, build_rivshot.bat, build_test.bat, build_surrogate_test.bat, build_thumb_test.bat.

The build environment is configured by build\env.bat, which auto-detects the newest MSVC toolset and Windows SDK via vswhere. It deliberately avoids vcvars64.bat because that script aborts when the optional cmake developer extension is absent.


Installing

Registration writes the COM class, the .riv association, and the approved-preview-handlers entry under HKEY_CURRENT_USER\Software\Classesper-user, so no administrator rights are required (the same scheme Microsoft's own preview-handler sample uses).

# install
install\register.ps1

# uninstall
install\unregister.ps1

Equivalent manual routes: regsvr32 build\bin\RivePeek.dll, or edit + merge install\RivePeek.reg.

After installing, open Explorer, enable the preview pane (Alt + P) and click a .riv file. The handler is loaded by the native 64-bit prevhost.exe surrogate (AppID {6d2b5079-2f0b-48dd-ab7f-97cec514d30b}).


Testing

# Render one file headlessly
build\bin\rivshot.exe sample.riv sample.png 512

# Exercise the entire COM handler in-process and capture the preview window
build\bin\preview_test.exe sample.riv capture.png

# Render every .riv in a folder and tally pass/fail
build\validate.ps1 -Dir "path\to\riv\files"

# Replicate Explorer's out-of-process activation (loads the handler in prevhost.exe)
build\bin\surrogate_test.exe sample.riv

# Produce the static thumbnail the file grid would show
build\bin\thumb_test.exe sample.riv thumb.png 256

Diagnostics: set the environment variable RIVEPEEK_LOG=1 to make the handler append a trace of each COM call (Initialize, DoPreview, GetThumbnail, errors) to %TEMP%\RivePeek.log. It is silent otherwise.

preview_test.exe performs the exact sequence the Shell does (DllGetClassObjectIClassFactory::CreateInstanceQueryInterface for every required interface → IInitializeWithStream::InitializeSetWindowDoPreview) and verifies it without needing the DLL registered.


Limitations

  • Text (WITH_RIVE_TEXT, HarfBuzz + SheenBidi) and flexbox layout (WITH_RIVE_LAYOUT, Yoga) are both supported. Vector art, shapes, gradients, clipping, raster images, image meshes, bones, constraints, state machines, text and layout all render. Audio and scripting remain unsupported.
  • Scripting (Rive's experimental scripted objects) is not supported; such objects are skipped on import. One corpus file exercises a destruction-order bug in those objects — the SEH teardown guard contains it (blank preview) rather than crashing.
  • Blend modes are fully supported (all 15 Rive modes via the Direct2D Blend effect). One caveat: a blended shape inside a clip composites against the pre-clip backdrop, since the clip is realized with a D2D layer whose contents aren't yet flattened when the backdrop is sampled.
  • Files using a different Rive major version than the bundled runtime (currently 7) are reported as unsupported.
  • Adding text/layout is a forward path: build the relevant runtime dependencies, define WITH_RIVE_TEXT / WITH_RIVE_LAYOUT, and implement Factory::decodeFont.

Troubleshooting

Symptom Fix
Preview pane is blank / shows nothing Make sure it's the Preview pane (Alt + P), not the Details pane. Re-run install\register.ps1 (it restarts Explorer).
.riv shows a generic picture/file icon Old thumbnail cache. Restart Explorer, or clear it: taskkill /f /im explorer.exe & del /q "%LOCALAPPDATA%\Microsoft\Windows\Explorer\thumbcache_*.db" & start explorer.
Nothing happens at all Confirm Folder Options ▸ View ▸ "Show preview handlers in preview pane" is enabled.
Want to see what the handler is doing Set RIVEPEEK_LOG=1 and read %TEMP%\RivePeek.log — it traces every COM call.
Build can't overwrite RivePeek.dll The DLL is loaded by a running prevhost.exe/Explorer. Close previews (or taskkill /f /im prevhost.exe) and rebuild.

Roadmap

  • WiX MSI installer (installer/ — dual-scope per-user / per-machine, WixUI_Advanced); attached to each release
  • Code-sign the DLL and MSI (Authenticode) — the current installer is unsigned
  • Full blend-mode support — all 15 Rive blend modes via the Direct2D Blend effect (ID2D1DeviceContext), with a clean srcOver fallback
  • Text rendering (WITH_RIVE_TEXT — HarfBuzz + SheenBidi, statically linked); shaping + variable/embedded fonts
  • Yoga-based layout (WITH_RIVE_LAYOUT — rive-app/yoga, statically linked); flexbox positioning for responsive artboards
  • Idle pause — the animation timer stops advancing when the host/preview isn't in the foreground, and resize/reparent use SWP_NOACTIVATE so the pane never steals keyboard focus from Explorer's file list

Contributing

Contributions are welcome — see CONTRIBUTING.md for how to build, the project layout, coding conventions, and good first issues (the roadmap items above are all self-contained starting points).


Credits & license

  • Built on the Rive C++ runtime (MIT), included as a submodule.
  • COM preview-handler structure (interface set, QISearch dispatch, per-user HKCU registration, prevhost surrogate AppID) follows Microsoft's canonical RecipePreviewHandler sample.
  • RivePeek itself is MIT licensed — see LICENSE.

About

RivePeek — native Windows Explorer preview handler that renders animated Rive (.riv) files in the preview pane via a Direct2D backend over the Rive C++ runtime.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors