简体   繁体   English

了解 CLR/System.IO.FileNotFoundException “无法加载文件或程序集......或其依赖项之一”

[英]understanding CLR/System.IO.FileNotFoundException "Could not load file or assembly ... or one of its dependencies"

I have an issue with using System.Text.Json insinde my C# class library, which is a SolidWorks addin.我在我的 C# 类库中使用System.Text.Json时遇到问题,这是一个 SolidWorks 插件。 It is probably an instance of DLL hell as described here .它可能是此处描述的 DLL 地狱的一个实例。

Since this approach does not work, I might be able to figure something out if I understand a bit more about this issue.由于这种方法不起作用,如果我对这个问题有更多了解,我可能会想出一些办法。 Maybe someone can help?也许有人可以帮忙?

First - my code.首先 - 我的代码。

My 'csproj' file:我的“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 &quot;$(TargetPath)&quot; /codebase" />
  </Target>
  <Target Name="Unregister" BeforeTargets="BeforeClean">
    <Exec Command="%windir%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe &quot;$(TargetPath)&quot; /u" />
  </Target>

</Project>

The relevant parts of my cs file:我的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) { ... }
    }
}

When I run SolidWorks after building (and thus, registering my dll in the codebase) and debug it, I get a runtime error on当我在构建后运行 SolidWorks(因此,在代码库中注册我的 dll)并调试它时,我得到一个运行时错误

var doc = System.Text.Json.JsonDocument.Parse(jsonText);

saying

Exception has occurred: CLR/System.IO.FileNotFoundException An exception of type 'System.IO.FileNotFoundException' occurred in System.Text.Json.dll but was not handled in user code: 'Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.发生异常:CLR/System.IO.FileNotFoundException System.Text.Json.dll 中发生“System.IO.FileNotFoundException”类型的异常,但未在用户代码中处理:“无法加载文件或程序集”System.Runtime .CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 或其依赖项之一。 The system cannot find the file specified.'该系统找不到指定的文件。'

. . As mentioned above, I did try adding如上所述,我确实尝试添加

<PropertyGroup>
  <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
  <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

to my csproj file, resulting in the following .dll.config file in my bin/Debug folder:到我的 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>

but the runtime error still occurs.但运行时错误仍然发生。

So I'd like to actually understand the issue instead of just following cooking recipes.所以我想真正理解这个问题,而不是仅仅遵循烹饪食谱。 Here are some things I tried and thoughts:以下是我尝试过的一些事情和想法:

  1. The error says the issue is inside System.Text.Json.dll .该错误表明问题出在System.Text.Json.dll内部。 I understand it so that the file System.Text.Json.dll , which lies in location A , expects a file System.Runtime.CompilerServices.Unsafe.dll of version 4.0.4.1 in location B , but in location B there is a different version of file System.Runtime.CompilerServices.Unsafe.dll (or no file of that name at all).我理解它,因此位于位置A的文件System.Text.Json.dll期望位置B的版本为4.0.4.1的文件System.Runtime.CompilerServices.Unsafe.dll ,但在位置B有一个不同的文件System.Runtime.CompilerServices.Unsafe.dll的版本(或根本没有该名称的文件)。

=> Can anyone tell me which locations A and B we are talking about? =>谁能告诉我我们在谈论哪些地点AB Is it a certain folder?是某个文件夹吗? Is it the GAC?是GAC吗? In case it is the GAC, are we actually talking about files, or something else?如果是 GAC,我们实际上是在谈论文件还是其他什么?

  1. I checked the (for me) most probable location, the folder $myProjectPath\bin\Debug\net48 .我检查了(对我来说)最可能的位置,文件夹$myProjectPath\bin\Debug\net48 There I can find (amongst others) both dlls System.Text.Json.dll and System.Runtime.CompilerServices.Unsafe.dll .在那里我可以找到(除其他外)两个dll System.Text.Json.dllSystem.Runtime.CompilerServices.Unsafe.dll I opened both in some decompilation tool to check their versions and the versions of their references.我在一些反编译工具中打开了它们以检查它们的版本和它们的参考版本。 This is what I found:这是我发现的:
  • System.Text.Json.dll has version 6.0.0.2 and references System.Runtime.CompilerServices.Unsafe.dll of version 6.0.0.0 . System.Text.Json.dll的版本为6.0.0.2并引用System.Runtime.CompilerServices.Unsafe.dll的版本6.0.0.0

  • System.Runtime.CompilerServices.Unsafe.dll has version 6.0.0.0 . System.Runtime.CompilerServices.Unsafe.dll的版本为6.0.0.0

=> So the required version and the present version of System.Runtime.CompilerServices.Unsafe.dll do align. =>所以所需版本和System.Runtime.CompilerServices.Unsafe.dll的当前版本确实对齐。 Why do I then get the error?为什么我会收到错误消息? Doesn't this just mean that location A and B are NOT $myProjectPath\bin\Debug\net48 ?这不只是意味着位置AB不是$myProjectPath\bin\Debug\net48吗? Or is the referenced version ignored under some circumstances?还是在某些情况下忽略了引用的版本? What kind of cirumstances?什么样的情况?

  1. I built a standalone console app, just using System.Text.Json and containing the two lines我构建了一个独立的控制台应用程序,仅使用System.Text.Json并包含两行

    var jsonText = "{ \"foo\": { \"bar\": 2 } }";

    var doc = System.Text.Json.JsonDocument.Parse(jsonText);

inside it Main method.在里面Main方法。 No runtime error occurs there.那里没有发生运行时错误。 So SolidWorks must be the culprit somehow , even if it is not mentioned in the runtime error message.所以 SolidWorks 一定是罪魁祸首,即使它没有在运行时错误消息中提及。

  1. This article covers dll hell and gives suggestions for troubleshooting.本文涵盖了 dll 地狱,并提供了故障排除建议。 I checked the modules (Debug -> Windows -> Modules) in Visual Studio.我检查了 Visual Studio 中的模块(调试 -> Windows -> 模块)。 It turns out that just before the error occurs事实证明,就在错误发生之前
  • System.Text.Json version 6.0.0.0 is already loaded (from my $myProjectPath\bin\Debug\net48 folder). System.Text.Json版本6.0.0.0已加载(从我的$myProjectPath\bin\Debug\net48文件夹)。

  • System.Runtime.CompilerServices.Unsafe is not loaded. System.Runtime.CompilerServices.Unsafe未加载。

=> But if System.Runtime.CompilerServices.Unsafe has not been loaded before, why does System.Text.Json want to load version 4.0.4.1 instead of the version specified in its own references ( 6.0.0.0 )? =>但是如果之前没有加载过System.Runtime.CompilerServices.Unsafe为什么System.Text.Json要加载版本4.0.4.1而不是自己引用中指定的版本( 6.0.0.0 )? Where does the 4.0.4.1 come from? 4.0.4.1是从哪里来的?

Thanks to M Kloster's comment, I could work around the issue by manually loading the assembly - although this unfortunately does not help understanding the issue.感谢 M Kloster 的评论,我可以通过手动加载程序集来解决这个问题——尽管不幸的是这无助于理解这个问题。

First I inserted the line首先我插入了行

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);

into the ConnectToSW method (as first line).进入ConnectToSW方法(作为第一行)。

Then I implemented MyResolveEventHandler like so:然后我像这样实现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;
}

Now, whenever an assembly cannot be loaded by the automatic mechanism, MyResolveEventHandler will be called.现在,只要自动机制无法加载程序集,就会调用MyResolveEventHandler

Here I just check if it is System.Text.Json.dll trying to load System.Runtime.CompilerServices.Unsafe version 4.0.4.1 , and if yes, I return the assembly System.Runtime.CompilerServices.Unsafe.dll from System.Text.Json.dll 's location folder.在这里我只是检查是否是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的位置文件夹。

Strangely, this allowed me to confirm that the System.Text.Json.dll trying to load System.Runtime.CompilerServices.Unsafe version 4.0.4.1 really is the one located in my $myProjectPath\bin\Debug\net48 folder.奇怪的是,这让我可以确认尝试加载System.Runtime.CompilerServices.Unsafe版本4.0.4.1System.Text.Json.dll确实是位于我的$myProjectPath\bin\Debug\net48文件夹中的那个。 Which makes no sense to me, as the decompilation tool told me that the file $myProjectPath\bin\Debug\net48\System.Text.Json.dll references System.Runtime.CompilerServices.Unsafe version 6.0.0.0 , not 4.0.4.1 .这对我来说毫无意义,因为反编译工具告诉我文件$myProjectPath\bin\Debug\net48\System.Text.Json.dll引用System.Runtime.CompilerServices.Unsafe version 6.0.0.0 ,而不是4.0.4.1

And as I said in my question, the issue does not occur outside of SolidWorks (eg in a standalone console app).正如我在问题中所说,该问题不会出现在 SolidWorks 之外(例如,在独立控制台应用程序中)。 So SolidWorks must somehow interfere in the (automatic) assembly resolving mechanism, maybe redirecting bindings?所以 SolidWorks 必须以某种方式干预(自动)装配体解析机制,也许是重定向绑定? Very mysterious... Is there a way to turn that off?很神秘...有没有办法把它关掉?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 System.IO.FileNotFoundException:无法加载文件或程序集“程序集名称”或其依赖项之一 - System.IO.FileNotFoundException: Could not load file or assembly 'name of assembly' or one of its dependencies System.IO.FileNotFoundException:部署应用程序时无法加载文件或程序集“X”或其依赖项之一 - System.IO.FileNotFoundException: Could not load file or assembly 'X' or one of its dependencies when deploying the application System.IO.FileNotFoundException:无法加载文件或程序集“Windows”或其依赖项之一 - System.IO.FileNotFoundException: Could not load file or assembly 'Windows' or one of its dependencies 如何修复 System.IO.FileNotFoundException:无法加载文件或程序集“ScanAPIHelper.dll”或其依赖项之一 - How to fix System.IO.FileNotFoundException: Could not load file or assembly 'ScanAPIHelper.dll' or one of its dependencies 无法加载文件或程序集System.IO.FileNotFoundException - Could not load file or assembly System.IO.FileNotFoundException System.IO.FileNotFoundException:无法加载文件或程序集 - System.IO.FileNotFoundException: Could not load file or assembly System.IO.FileNotFoundException: '无法加载文件或程序集 - System.IO.FileNotFoundException: 'Could not load file or assembly 奇怪的错误:System.IO.FileNotFoundException:无法加载文件或程序集 - Weird Error: System.IO.FileNotFoundException: Could not load file or assembly System.IO.FileNotFoundException: 无法加载文件或程序集 C# - System.IO.FileNotFoundException: Could not load file or assembly C# 无法加载程序集&gt;&gt; System.IO.FileNotFoundException:无法加载文件或程序集&#39;System.Core, - Unable to Load assembly>>System.IO.FileNotFoundException: Could not load file or assembly 'System.Core,
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM