stride3d/stride · error · DirectoryNotFoundException
Could not locate "Program Files" folder.
Error message
Could not locate "Program Files" folder.
What it means
Thrown by WinPixNative.LoadPixGpuCapturer (via GetLatestWinPixGpuCapturerPath) when Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) returns an empty string, so the PIX GPU capturer DLL cannot be located. This only runs on the PIX GPU-capture path, typically in debug builds.
Solutions
- Ensure the application runs on Windows with the standard Program Files folder available (SYSTEMDRIVE\Program Files / %ProgramFiles%).
- Disable PIX GPU capture (remove the capture trigger / PIX interop) on platforms where it cannot work.
- Install Microsoft PIX so the path can be resolved and validated once the folder is found.
Example fix
// before: PIX capture enabled unconditionally
GraphicsDeviceFactory.EnableGPUCaptureAssertions = true;
// after: guard for Windows PIX availability
if (OperatingSystem.IsWindows() && Platform.IsWindowsDesktop)
GraphicsDeviceFactory.EnableGPUCaptureAssertions = true; Defensive patterns
Strategy: fallback
Validate before calling
if (!OperatingSystem.IsWindows())
{
log.Info("PIX GPU capture unsupported on this OS; skipping");
return;
}
var pf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (string.IsNullOrEmpty(pf)) { log.Warn("Program Files not resolvable; PIX capture skipped"); return; } Type guard
bool CanUsePixCapture() => OperatingSystem.IsWindows()
&& !string.IsNullOrEmpty(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)); Try / catch
try { WinPixNative.Initialize(); }
catch (DirectoryNotFoundException ex) { log.Warn("PIX capture unavailable: " + ex.Message); } Prevention
- Enable PIX capture only on Windows desktop with the standard Program Files layout.
- Skip capture hooks in non-Windows, container, and service contexts.
- Wrap PIX interop initialization so capture failures never crash the app.
When it happens
Trigger: Enabling PIX GPU capture (via a debugger/Profiler attached capture request) on a system where the Program Files environment variable/special folder is not resolvable — e.g. running on non-Windows, a sandbox, or an environment with redirected/missing system folders.
Common situations: Capturing on Linux/macOS where the WinPIX path makes no sense; running under a service account or container with stripped environment variables; CI machines without standard Windows folder layout.
Related errors
- Microsoft PIX not found under
- No PIX installation found.
- Bundle could not be resolved
- Cannot detect dependencies of projet
- Could not find a MSBuild installation (expected 16.0 or…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/cc5e569d9cf6f4a0.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Direct3D12/WinPixNative.cs:84
/// This method is typically called before initializing GPU capture or profiling with Microsoft PIX.
/// If the DLL is already loaded, calling this method has no effect.
/// </remarks>
public static void LoadPixGpuCapturer()
{
IntPtr moduleHandle = GetModuleHandle(CapturerDllName);
if (moduleHandle == IntPtr.Zero)
{
LoadLibrary(GetLatestWinPixGpuCapturerPath());
}
//
// Helper to locate the latest installed "WinPixGpuCapturer.dll".
//
static string GetLatestWinPixGpuCapturerPath()
{
string programFilesPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (string.IsNullOrEmpty(programFilesPath))
throw new DirectoryNotFoundException("Could not locate \"Program Files\" folder.");
string pixInstallationPath = Path.Combine(programFilesPath, "Microsoft PIX");
if (!Directory.Exists(pixInstallationPath))
throw new DirectoryNotFoundException($"Microsoft PIX not found under \"{programFilesPath}\".");
string newestVersionFound = null;
// Enumerate all subdirectories, looking for the one with the highest version number
foreach (var dir in Directory.EnumerateDirectories(pixInstallationPath))
{
var dirName = Path.GetFileName(dir);
if (string.IsNullOrEmpty(dirName))
continue;
if (newestVersionFound is null || string.CompareOrdinal(newestVersionFound, dirName) < 0)
{
newestVersionFound = dirName;
}View on GitHub (pinned to 96fad776d2)