{"record":{"id":"9a72ef1ebe47f50c","repo":"beeradmoore/dlss-swapper","slug":"failed-to-load-dll","errorCode":null,"errorMessage":"Failed to load DLL","messagePattern":"Failed to load DLL","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Helpers/FSR31/FSR31Helper.cs","lineNumber":35,"sourceCode":"    [DllImport(\"kernel32.dll\", SetLastError = true)]\n    [return: MarshalAs(UnmanagedType.Bool)]\n    private static extern bool FreeLibrary(IntPtr hModule);\n\n    // Define a delegate for the ffxQuery function\n    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n    private delegate FfxApiReturnCodes ffxQueryDelegate(IntPtr context, ref QueryDescGetVersions header);\n\n    public static List<string?> GetVersions(string dllPath)\n    {\n        if (Path.Exists(dllPath) == false)\n        {\n            return new List<string?>();\n        }\n        Logger.Info($\"AMDFidelityFXAPI - Loading {dllPath}\");\n        var hModule = LoadLibrary(dllPath);\n        if (hModule == IntPtr.Zero)\n        {\n            throw new Exception(\"Failed to load DLL\");\n        }\n\n        try\n        {\n            var pAddressOfFunctionToCall = GetProcAddress(hModule, \"ffxQuery\");\n            if (pAddressOfFunctionToCall == IntPtr.Zero)\n            {\n                throw new Exception(\"Failed to get function address\");\n            }\n\n            var ffxQuery = Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ffxQueryDelegate)) as ffxQueryDelegate;\n            if (ffxQuery is null)\n            {\n                throw new Exception(\"Failed to get function delegate\");\n            }\n\n            var versionQuery = new QueryDescGetVersions();\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/beeradmoore/dlss-swapper/blob/ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb/src/Helpers/FSR31/FSR31Helper.cs#L17-L53","documentation":"FSR31Helper.GetVersions loads the AMD FidelityFX API DLL via LoadLibrary to call its ffxQuery export and query FSR 3.1 driver/runtime versions. When LoadLibrary returns IntPtr.Zero the DLL could not be loaded, so the helper throws 'Failed to load DLL'. This is a native interop failure: the module never made it into the process address space.","triggerScenarios":"Calling GetVersions when the DLL at dllPath is missing, is blocked (downloaded file with Mark-of-the-Web, antivirus quarantine), has unsatisfied native dependencies (missing VC++ runtime, driver DLLs), or the architecture (x86/x64/ARM64) does not match the process. Also when amdxc64.dll / the FidelityFX API is absent because GPU drivers are outdated or non-AMD GPUs are present.","commonSituations":"Users without current AMD drivers or with NVIDIA-only systems; x86 process trying to load an x64 DLL; DLL shipped without its dependency chain; SmartScreen/AV blocking unsigned DLLs in temp folders.","solutions":["Verify the file exists at dllPath (File.Exists) and that its bitness matches the process (x64 DLL in a 64-bit process) before calling LoadLibrary.","Update AMD Radeon/Adrenalin drivers (or install the FidelityFX API redistributable) so the DLL and its dependencies exist.","Run dependency inspection (Dependencies/dumpbin /dependents) to find missing dependent DLLs and install the VC++ redistributables.","Unblock the file (file Properties > Unblock, or remove the Zone.Identifier ADS) if Mark-of-the-Web is blocking it.","Check antivirus quarantine logs and whitelist the DLL if it was removed."],"exampleFix":"// before\nvar hModule = LoadLibrary(dllPath);\nif (hModule == IntPtr.Zero)\n    throw new Exception(\"Failed to load DLL\");\n// after\nvar hModule = LoadLibrary(dllPath);\nif (hModule == IntPtr.Zero)\n{\n    var err = Marshal.GetLastWin32Error();\n    throw new Exception($\"Failed to load DLL '{dllPath}' (Win32Error={err}, exists={File.Exists(dllPath)})\");\n}\n","handlingStrategy":"validation","validationCode":"if (!File.Exists(dllPath))\n    throw new FileNotFoundException($\"FidelityFX DLL not found: {dllPath}\");\n// optional: verify bitness matches the process before LoadLibrary","typeGuard":"static bool CanLoadLibrary(string dllPath)\n{\n    var h = LoadLibrary(dllPath);\n    if (h != IntPtr.Zero) { FreeLibrary(h); return true; }\n    return false;\n}","tryCatchPattern":"try\n{\n    var versions = FSR31Helper.GetVersions();\n}\ncatch (Exception ex) when (ex.Message == \"Failed to load DLL\")\n{\n    Logger.Warn(ex, $\"Could not load {dllPath}; FSR 3.1 version info unavailable. Check drivers and bitness.\");\n}","preventionTips":["Check File.Exists and process bitness before calling the helper.","Ensure the process is 64-bit when loading 64-bit FidelityFX DLLs.","Keep AMD drivers / VC++ redistributables current on target machines.","Unblock downloaded DLLs (Zone.Identifier) and whitelist them in AV policies.","Call Marshal.GetLastWin32Error immediately after failed LoadLibrary for diagnosable messages."],"tags":["native-interop","dll","fsr","windows"],"backgroundTag":"missing-dependency","analyzedSha":"ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb","analyzedAt":"2026-09-15T05:25:32.979Z","contentChangedAt":"2026-09-15T05:25:32.979Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}