Как включить логирование ошибок привязки сборок (Fusion) в .NET для отладки?
Что такое Fusion Logging и зачем он нужен?
Fusion Logging (или логер привязки сборок) — это встроенный механизм .NET Framework, который записывает подробную информацию о том, как CLR (Common Language Runtime) находит и загружает сборки. Когда возникает FileLoadException или BadImageFormatException, эти логи показывают, какую именно версию сборки запрашивает приложение, где среда ищет эту сборку и почему поиск завершается неудачей.
Способ 1: Включение через реестр Windows (рекомендуется для разработки)
Самый надёжный способ — установить значения в реестре. Это включает логирование глобально для всех .NET-приложений на машине (до перезагрузки или до отмены настройки).
- Откройте regedit.exe (Пуск → Выполнить → regedit).
- Перейдите в ветку:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion. Если ветки нет — создайте её вручную (правой кнопкой по Microsoft → Создать → Раздел). - Создайте параметр DWORD (32 бита) с именем
EnableLogи значением1. - Создайте параметр DWORD с именем
ForceLogи значением1(чтобы логировать даже успешные привязки). - Создайте строковый параметр REG_SZ с именем
LogPathи значением, например,C:\FusionLogs\(папка должна существовать).
После этого перезапустите ваше приложение. В папке C:\FusionLogs\ появятся файлы вида DefaultDomain.1.log, DefaultDomain.2.log и т.д. Откройте их блокнотом — вы увидите что-то вроде:
*** Assembly Binder Log Entry (10/05/2023 @ 14:32:15) ***
The operation failed.
Bind result: hr = 0x80131040. No description available.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable C:\MyApp\MyApp.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: DisplayName = Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
(Fully-specified)
LOG: Appbase = file:///C:/MyApp/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = MyApp.exe
...
LOG: Attempting download of new URL file:///C:/MyApp/Newtonsoft.Json.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\MyApp\Newtonsoft.Json.dll
LOG: Entering download cache setup phase...
LOG: Assembly Name is: Newtonsoft.Json, Version=13.0.1.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
LOG: Found assembly version 13.0.1.0. But request was for version 12.0.0.0.
ERR: The assembly reference did not match the found assembly.
Из лога видно, что приложение запрашивает 12.0.0.0, а на диске лежит 13.0.1.0. Теперь понятно, что нужно исправить bindingRedirect в конфиге.
Способ 2: Включение через код (для точечной отладки)
Если не хотите лезть в реестр, можно включить логирование программно в начале Main():
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
// Включаем логирование в текущую директорию
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "app.exe.config");
// Устанавливаем переменные среды для Fusion
Environment.SetEnvironmentVariable("FUSIONLOG_PATH", @".\FusionLogs");
Environment.SetEnvironmentVariable("FUSIONLOGFILE", "fusion.log");
// Ваш код...
var loader = new ConfigLoader();
var config = loader.LoadConfig<MyConfig>("config.json");
}
}
Но учтите: этот метод работает не всегда надёжно, так как некоторые настройки считываются CLR до выполнения вашего кода. Поэтому способ с реестром предпочтительнее.
Как отключить логирование?
После отладки обязательно отключите логирование, иначе оно будет замедлять работу всех .NET-приложений:
- Удалите параметры
EnableLogиForceLogиз реестра (или поставьте 0). - Удалите папку с логами.
Бонус: исправление вашей проблемы с Newtonsoft.Json
Добавьте в app.config корректный bindingRedirect:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.1.0" newVersion="13.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Обратите внимание: oldVersion должен перекрывать все запрашиваемые старые версии (от 0.0.0.0 до текущей).
Альтернатива: использование утилиты FusLogVw (Fusion Log Viewer)
Если вам неудобно вручную копаться в реестре и текстовых логах, используйте встроенную графическую утилиту FusLogVw.exe. Она входит в состав Windows SDK (например, Windows 10 SDK) и находится в папке:
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\FusLogVw.exe
Запустите её от имени администратора. В окне утилиты:
- Нажмите Settings.
- Выберите Enable all binds (логировать все привязки) или Enable binds to disk (только неудачные).
- Укажите путь для сохранения логов.
- Нажмите OK и запустите ваше приложение.
Логи будут отображаться в реальном времени в таблице. Вы сможете фильтровать по имени сборки, видеть HRESULT ошибки и полный стек вызовов. Это гораздо удобнее, чем читать сотни строк в блокноте.
Важно: Не забывайте отключать логирование через ту же утилиту после завершения отладки — нажмите Disable в настройках.
Если у вас нет Windows SDK, скачайте его с официального сайта Microsoft (бесплатно). Это также даст вам доступ к другим полезным инструментам, таким как CorFlags.exe и G
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги