在C++/CLI项目中识别有问题的依赖关系
在C++/CLI项目中识别有问题的依赖关系
我的应用程序编译没有问题,但是我遇到了以下的运行时错误:
System.IO.FileNotFoundException was unhandled HResult=-2147024770 Message=无法加载文件或程序集 {Wrapper} 或其某个依赖项。找不到指定的模块。
调用应用程序中对Wrapper的引用看起来是正确的。Wrapper dll存在于正确的位置。
这个项目在别人的系统上曾经能够成功构建和运行,我看过几次演示。但是那个人/电脑现在不可用了。自从上次成功构建和运行以来,一些依赖项的路径发生了改变,我已经修复了所有与此相关的编译错误。
为了澄清我的项目结构:
Digraph G
{
App [ label = "我的C#应用程序"]
Wrapper [ label = "C++/CLI包装器"]
Lib [ label = "C++库"]
Dll [ label = "我的辅助C# DLL"]
CDep [ label = "由CMake管理的一系列深层C++依赖项,Wrapper的相对路径是硬编码的。"]
App->Wrapper->Lib->CDep;
App->Dll->Wrapper->CDep;
}
Wrapper是一个C++/CLI包装器,用来包装一个C++库。当我们尝试加载应用程序中具有Wrapper的using语句的类时,就会触发这个错误。
Wrapper确实有很多依赖项,但错误信息没有指明哪个依赖项有问题。这是一个庞大而复杂的系统,其中大部分是由其他团队构建的。C++组件使用CMake来正确获取所有的依赖项,但是CMake本身并不支持C#。
我尝试使用fuslogvw来查找绑定错误,但除非我改变设置以包括所有绑定,否则它什么都不显示;即使显示了成功的绑定,也没有任何有用的信息。
http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.100).aspx
路径很长,但没有超过256个字符。
在Dll的编译中,我收到了一个警告(见上面的图):
Warning 1 正在构建的项目的处理器架构“MSIL”与引用“{cli_wrapper.dll}”的处理器架构“AMD64”不匹配。这种不匹配可能会导致运行时错误。请考虑通过配置管理器更改项目的目标处理器架构,以使项目和引用之间的处理器架构一致,或者依赖于与项目的目标处理器架构匹配的引用的处理器架构。
在配置管理器中,Dll正在构建为平台“Any CPU”,Wrapper正在构建为“x64”。我将dll改为了x64,但仍然得到运行时错误。
Could not load file or assembly or one of its dependencies
进行了清理,删除了构建目录的内容。没有变化。
重新打开Visual Studio。没有变化。
尝试更改程序集名称、默认命名空间和项目名称以匹配。没有变化。
我相信我们必须编译为64位。我们依赖于一个64位的C++库。
Could not load file or assembly ... The parameter is incorrect
我是本地管理员。
How to enable assembly bind failure logging (Fusion) in .NET
尝试了注册表设置,但它们似乎只是fuslogvw的设置。没有改善可用的日志数据。
许多其他类似的问题都有针对ASP或服务安装的特定答案。
问题原因:在C++/CLI项目中,使用了模拟用户,但是模拟用户没有对GAC(全局程序集缓存)或包含某些dll的文件夹拥有权限。解决方法是要么为该用户授予权限,要么在模拟开始之前加载依赖项。
在C++/CLI项目中,有时会遇到一个问题,即使用模拟用户时,模拟用户没有对GAC或包含某些dll的文件夹拥有权限。这会导致依赖项无法正确加载,进而导致项目出现问题。
解决这个问题的方法有两种。一种是为模拟用户授予对GAC和相关文件夹的权限。另一种是在模拟开始之前,先加载依赖项。
下面是一个示例代码,展示了如何在C++/CLI项目中进行模拟用户权限的授予和依赖项加载的调整:
// 首先,授予模拟用户对GAC和相关文件夹的权限 ... // 授予权限的代码 // 然后,在模拟开始之前,加载依赖项 ... // 加载依赖项的代码 // 开始模拟用户 ... // 模拟用户的代码
通过这样的调整,可以确保模拟用户有权限访问GAC和相关文件夹,以及正确加载项目所需的依赖项。这样,就可以避免因权限问题而导致的项目错误。