[英]System.IO.FileNotFoundException: Could not load file or assembly 'name of assembly' or one of its dependencies
[英]understanding CLR/System.IO.FileNotFoundException "Could not load file or assembly ... or one of its dependencies"
我在我的 C# 类库中使用System.Text.Json
时遇到问题,这是一个 SolidWorks 插件。 它可能是此处描述的 DLL 地狱的一个实例。
由于这种方法不起作用,如果我对这个问题有更多了解,我可能会想出一些办法。 也许有人可以帮忙?
首先 - 我的代码。
我的“csproj”文件:
<Project Sdk="Microsoft.NET.Sdk">
<!-- general stuff -->
<PropertyGroup>
<TargetFrameworks>net48</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>
<!-- references: the top two are SolidWorks API (needed for making a SolidWorks addin -->
<ItemGroup>
<PackageReference Include="com.solidworks.core" Version="29.5.1" />
<PackageReference Include="com.solidworks.tools" Version="21.5.0" />
<PackageReference Include="System.Text.Json" Version="6.0.2" />
</ItemGroup>
<!-- In order to have the addin available within SolidWorks,
it's dll needs to be registered in the codebase. For convenience
we automatically register on build and unregister on clean. -->
<Target Name="Register" AfterTargets="AfterBuild">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe "$(TargetPath)" /codebase" />
</Target>
<Target Name="Unregister" BeforeTargets="BeforeClean">
<Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe "$(TargetPath)" /u" />
</Target>
</Project>
我的cs
文件的相关部分:
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using SolidWorks...; // all the SolidWorks usings required
namespace SwxAddin
{
[Guid("acb6f17b-9738-4f11-a324-30e05625ff89")]
[ComVisible(true)]
public class SwxAddinImpl : ISwAddin
{
// will be called on addin load in SolidWorks
public bool ConnectToSW(object swx, int addinId)
{
var jsonText = "{ \"foo\": { \"bar\": 2 } }";
var doc = System.Text.Json.JsonDocument.Parse(jsonText); // exception occurs
return swx != null;
}
// will be called on addin unload in SolidWorks
public bool DisconnectFromSW() { return true; }
// This is run when registering the dll. It writes some stuff into the
// SolidWorks registry to make the addin available.
[ComRegisterFunction]
protected static void RegisterFunction(Type type) { ... }
// This is run when unregistering the dll. It removes the stuff from the
// SolidWorks registry that was written into it by RegisterFunction.
[ComUnregisterFunction]
protected static void UnregisterFunction(Type type) { ... }
}
}
当我在构建后运行 SolidWorks(因此,在代码库中注册我的 dll)并调试它时,我得到一个运行时错误
var doc = System.Text.Json.JsonDocument.Parse(jsonText);
说
发生异常:CLR/System.IO.FileNotFoundException System.Text.Json.dll 中发生“System.IO.FileNotFoundException”类型的异常,但未在用户代码中处理:“无法加载文件或程序集”System.Runtime .CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 或其依赖项之一。 该系统找不到指定的文件。'
. 如上所述,我确实尝试添加
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
到我的 csproj 文件,从而在我的 bin/Debug 文件夹中生成以下.dll.config
文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
但运行时错误仍然发生。
所以我想真正理解这个问题,而不是仅仅遵循烹饪食谱。 以下是我尝试过的一些事情和想法:
System.Text.Json.dll
内部。 我理解它,因此位于位置A
的文件System.Text.Json.dll
期望位置B
的版本为4.0.4.1
的文件System.Runtime.CompilerServices.Unsafe.dll
,但在位置B
有一个不同的文件System.Runtime.CompilerServices.Unsafe.dll
的版本(或根本没有该名称的文件)。 =>谁能告诉我我们在谈论哪些地点A
和B
? 是某个文件夹吗? 是GAC吗? 如果是 GAC,我们实际上是在谈论文件还是其他什么?
$myProjectPath\bin\Debug\net48
。 在那里我可以找到(除其他外)两个dll System.Text.Json.dll
和System.Runtime.CompilerServices.Unsafe.dll
。 我在一些反编译工具中打开了它们以检查它们的版本和它们的参考版本。 这是我发现的: System.Text.Json.dll
的版本为6.0.0.2
并引用System.Runtime.CompilerServices.Unsafe.dll
的版本6.0.0.0
。
System.Runtime.CompilerServices.Unsafe.dll
的版本为6.0.0.0
。
=>所以所需版本和System.Runtime.CompilerServices.Unsafe.dll
的当前版本确实对齐。 为什么我会收到错误消息? 这不只是意味着位置A
和B
不是$myProjectPath\bin\Debug\net48
吗? 还是在某些情况下忽略了引用的版本? 什么样的情况?
我构建了一个独立的控制台应用程序,仅使用System.Text.Json
并包含两行
var jsonText = "{ \"foo\": { \"bar\": 2 } }";
var doc = System.Text.Json.JsonDocument.Parse(jsonText);
在里面Main
方法。 那里没有发生运行时错误。 所以 SolidWorks 一定是罪魁祸首,即使它没有在运行时错误消息中提及。
System.Text.Json
版本6.0.0.0
已加载(从我的$myProjectPath\bin\Debug\net48
文件夹)。
System.Runtime.CompilerServices.Unsafe
未加载。
=>但是如果之前没有加载过System.Runtime.CompilerServices.Unsafe
,为什么System.Text.Json
要加载版本4.0.4.1
而不是自己引用中指定的版本( 6.0.0.0
)? 4.0.4.1
是从哪里来的?
感谢 M Kloster 的评论,我可以通过手动加载程序集来解决这个问题——尽管不幸的是这无助于理解这个问题。
首先我插入了行
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
进入ConnectToSW
方法(作为第一行)。
然后我像这样实现MyResolveEventHandler
:
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
var nameCompilerServicesUnsafe = "System.Runtime.CompilerServices.Unsafe";
if (args.Name == nameCompilerServicesUnsafe + ", Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
{
var assemblyPath = Assembly.GetCallingAssembly().Location;
if (Path.GetFileName(assemblyPath) == "System.Text.Json.dll")
{
var assemblyFolder = Path.GetDirectoryName(assemblyPath);
var pathCompilerServicesUnsafe = Path.Combine(assemblyFolder, nameCompilerServicesUnsafe + ".dll");
if (File.Exists(pathCompilerServicesUnsafe))
return Assembly.LoadFile(pathCompilerServicesUnsafe);
}
}
return null;
}
现在,只要自动机制无法加载程序集,就会调用MyResolveEventHandler
。
在这里我只是检查是否是System.Text.Json.dll
试图加载System.Runtime.CompilerServices.Unsafe
version 4.0.4.1
,如果是,我从System.Text.Json.dll
返回程序集System.Runtime.CompilerServices.Unsafe.dll
System.Text.Json.dll
的位置文件夹。
奇怪的是,这让我可以确认尝试加载System.Runtime.CompilerServices.Unsafe
版本4.0.4.1
的System.Text.Json.dll
确实是位于我的$myProjectPath\bin\Debug\net48
文件夹中的那个。 这对我来说毫无意义,因为反编译工具告诉我文件$myProjectPath\bin\Debug\net48\System.Text.Json.dll
引用System.Runtime.CompilerServices.Unsafe
version 6.0.0.0
,而不是4.0.4.1
。
正如我在问题中所说,该问题不会出现在 SolidWorks 之外(例如,在独立控制台应用程序中)。 所以 SolidWorks 必须以某种方式干预(自动)装配体解析机制,也许是重定向绑定? 很神秘...有没有办法把它关掉?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.