读取Firefox密码报System.ArgumentNullException异常如何解决
问题根源
pProc返回0x00000000不符合预期,说明GetProcAddress调用失败,未能从加载的nss3.dll中找到目标导出函数,传入空指针到Marshal.GetDelegateForFunctionPointer触发了参数空异常,可按以下步骤排查解决:
解决方案
- 先校验库加载状态
你当前的代码未判断LoadLibrary的返回结果,若mozglue.dll或nss3.dll本身加载失败,后续函数查找必然失败,可先将Firefox目录加入系统PATH避免依赖加载失败,再添加校验逻辑:// 把Firefox目录加入PATH,解决依赖库找不到的问题 string pathEnv = Environment.GetEnvironmentVariable("PATH"); Environment.SetEnvironmentVariable("PATH", $"{mozillaPath};{pathEnv}"); IntPtr mozglue = LoadLibrary(mozillaPath + "mozglue.dll"); if(mozglue == IntPtr.Zero) throw new Exception("加载mozglue.dll失败"); NSS3 = LoadLibrary(mozillaPath + "nss3.dll"); if(NSS3 == IntPtr.Zero) throw new Exception("加载nss3.dll失败"); - 匹配项目与Firefox架构
若你的C#项目生成架构为x86(32位),但系统安装的Firefox为64位,或反过来,会出现dll加载成功但无法找到导出函数的问题,建议将项目生成平台统一设置为x64,适配当前主流的64位Firefox版本。 - 适配新版本Firefox的函数名
较新版本的Firefox已不再导出NSS_Init函数,替换为NSS_InitReadWrite或NSS_Initialize,可修改函数查找逻辑:
若使用IntPtr pProc = GetProcAddress(NSS3, "NSS_InitReadWrite"); if(pProc == IntPtr.Zero) pProc = GetProcAddress(NSS3, "NSS_Initialize"); if(pProc == IntPtr.Zero) throw new Exception("未找到NSS初始化函数");NSS_Initialize,需要重新定义对应委托,它的入参数量更多:[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public delegate int NSSInitializeDelegate(string configdir, string certPrefix, string keyPrefix, string secmodName, uint flags); // 调用示例 NSSInitializeDelegate dll = (NSSInitializeDelegate)Marshal.GetDelegateForFunctionPointer(pProc, typeof(NSSInitializeDelegate)); return dll(configdir, null, null, null, 0); - 修正委托定义
你当前定义的委托返回值为long,但NSS原生接口返回的SECStatus本质是32位整型,在64位环境下会出现类型长度不匹配的问题,建议修改委托返回值为int:[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public delegate int DLLFunctionDelegate(string configdir);
内容的提问来源于stack exchange,提问作者BarrosKing
相关产品推荐
相关产品推荐

