Настройка лицензии

Где Doconut ищет ваш файл лицензии

Без лицензии Doconut всё равно отображает документы — каждая страница просто содержит водяной знак оценки. Эта страница описывает четыре способа предоставления лицензии и точный порядок приоритета, когда задано более одного.

Лицензия загружается один раз, во время AddDoconut(). Это изменение по сравнению с предыдущей библиотекой .NET Standard, где лицензия передавалась экземпляру Viewer или устанавливалась через статические вызовы Viewer.DoconutLicense(...) / Viewer.SetLicensePlugin(...). Эти методы не являются механизмом запуска в этом выпуске — см. руководство по миграции.

Четыре способа предоставить лицензию

Существует четыре: три явных источника в DoconutOptions — поток, сырое содержимое или путь к файлу — плюс автоматическое обнаружение, когда ни один из них не задан. Когда задано более одного, порядок приоритета точен:

LicenseStream превосходит LicenseContent превосходит LicensePath превосходит авто-поиск.

По пути

LicensePath передаётся в File.Exists точно так, как указано. Относительный путь разрешается относительно текущей рабочей директории процесса — а не папки вашего проекта и не папки, где находится Program.cs. Если путь не разрешается, Doconut не бросает исключение и не переходит к авто-поиску — он просто не загружает лицензию, и просмотрщик отображает водяные знаки. Авто-поиск запускается только когда ни LicensePath, ни LicenseContent, ни LicenseStream не заданы. Файлы лицензий плагинов в той же папке (Doconut.Viewer.<Capability>.lic) читаются вместе с ним, поэтому LicensePath и AddPlugin<...>() работают совместно, когда лицензии плагинов находятся рядом с основной лицензией.

Предпочтительно использовать абсолютный путь (например, построенный из IWebHostEnvironment.WebRootPath или AppContext.BaseDirectory), либо полностью опустить LicensePath и полагаться на автоматическое обнаружение ниже.

csharp
builder.Services.AddDoconut(options =>
{
    options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
});

По потоку

LicenseStream читается один раз при запуске — полезно, когда лицензия берётся из хранилища секретов, а не из файла на диске.

csharp
// Приоритет: LicenseStream > LicenseContent > LicensePath > авто-поиск.
builder.Services.AddDoconut(options =>
{
    options.LicenseStream = licenseStream;
});

По содержимому

LicenseContent принимает сам текст лицензии — из переменной окружения, базы данных или менеджера секретов:

csharp
// XML лицензии из базы данных, переменной окружения или менеджера секретов —
// нет файла на диске. Превосходит только LicenseStream.
builder.Services.AddDoconut(options =>
{
    options.LicenseContent = Environment.GetEnvironmentVariable("DOCONUT_LICENSE") ?? "";
});

Автоматическое обнаружение

Не настраивая ни один из трёх явных источников, Doconut ищет лицензию самостоятельно:

csharp
// Не настраивая ничего, Doconut ищет лицензию самостоятельно, только в этих двух папках:
//   1. {CurrentDirectory}/wwwroot
//   2. {AppContext.BaseDirectory}/wwwroot   (wwwroot внутри папки вывода сборки)
// Он ищет Doconut.lic первым, затем Doconut.Viewer.lic, а также любые per-capability
// файлы Doconut.Viewer.<Capability>.lic рядом с ним.
builder.Services.AddDoconut();

Папки для проверки, в порядке следования, и имена файлов, которые ищутся в каждой:

text
1. {CurrentDirectory}/wwwroot
2. {AppContext.BaseDirectory}/wwwroot

Filenames (checked in each folder above, in order):
  Doconut.lic                          — base viewer license (checked first)
  Doconut.Viewer.lic                   — base viewer license
  Doconut.Viewer.<Capability>.lic      — per-capability license, alongside the base license

Ничего за пределами папки wwwroot не читается: .lic в самой папке вывода или в wwwroot/lib игнорируется.

Если ранее вы передавали List<string> путей к лицензиям в конструктор Viewer — по одному на возможность — держите эти сопутствующие файлы рядом с Doconut.Viewer.lic и позвольте автоматическому обнаружению их подобрать. В DoconutOptions нет опции списка путей.

Скопировать лицензию в папку вывода

Когда процесс не запускается из папки проекта — опубликованное приложение, IIS, контейнер, тест‑раннер — первая проверка не находит файл, и вторая, {AppContext.BaseDirectory}/wwwroot, должна его найти. Тестовое приложение SDK копирует лицензии туда при каждой сборке с помощью этой цели MSBuild:

xml
<Target Name="CopyLicensesToOutput" AfterTargets="Build">
  <ItemGroup>
    <DoconutLicenseFiles Include="$(MSBuildProjectDirectory)\wwwroot\*.lic" />
    <StaleOutputLicenses Include="$(OutDir)wwwroot\*.lic" />
  </ItemGroup>
  <!-- Сначала удалить, чтобы переименование или удаление .lic в wwwroot также удаляло его из вывода. -->
  <Delete Files="@(StaleOutputLicenses)" />
  <Copy SourceFiles="@(DoconutLicenseFiles)" DestinationFolder="$(OutDir)wwwroot" />
</Target>

Назначение должно быть $(OutDir)wwwroot: .lic, скопированный в корень вывода, никогда не будет найден автоматическим поиском. Примеры LicensePath на этой странице указывают на то же место.

Держите файлы .lic вне системы контроля версий — развертывайте их рядом с приложением или внедряйте лицензию через LicenseContent или LicenseStream из вашего хранилища секретов.

Что происходит без лицензии

Отсутствующая лицензия не вызывает исключения. AddDoconut() успешно выполняется, приложение запускается, и просмотрщик работает — но каждая страница содержит водяной знак, и никакие дополнительные возможности не предоставляются.

Файл лицензии, который найден, но отклонён, отличается. Неверная подпись, вмешательство, черный список или сборка вне окна версии лицензии вызывают у OpenDocumentAsync исключение LicenseException с License.RejectionMessage. Календарно просроченная лицензия без сообщения об отклонении продолжает работать в режиме с водяным знаком.

Плагинам нужны возможности

Регистрация плагина без соответствующего права отличается: при отсутствии лицензии, устаревшем файле TRIAL или платной лицензии без этой возможности AddDoconut() бросает InvalidOperationException, поэтому приложение не стартует. Например, регистрация плагина Converter без лицензии, предоставляющей Converter:

text
InvalidOperationException: The Converter plugin is registered via AddPlugin but no active
license grants Converter. Remove the AddPlugin<...>() call or install a license (or
trial/demo) that includes Converter.

Сообщение сразу подсказывает решение: либо удалить вызов options.AddPlugin<...>() для этого плагина, либо установить платную лицензию или активную временную/демо (NFR) лицензию, предоставляющую возможность. Временные регистрации допускаются после истечения срока, чтобы уже настроенное приложение могло работать в упрощённом режиме вместо краха при перезапуске; после истечения их возможности всё равно отзываются.

Проверка загруженной лицензии

Используйте IDoconutLicenseService, тот же источник правды, что и у SDK, чтобы открыть аутентифицированный диагностический endpoint или управлять флагами функций. Не возвращайте содержимое лицензии или ключи.

csharp
app.MapGet("/api/doconut/license", (IDoconutLicenseService license) => Results.Ok(new
{
    viewer = license.IsViewerLicensed || license.IsTemporary,
    temporary = license.IsTemporary,
    search = license.IsCapabilityGranted(LicenseCapability.Search),
    annotation = license.IsCapabilityGranted(LicenseCapability.Annotation),
    converter = license.HasConverter,
    dicom = license.HasDicom
}));

Лицензия читается во время регистрации AddDoconut(). ResetLicense в настоящее время является совместимым свойством без активного пути перезагрузки, поэтому замена файла лицензии требует перезапуска приложения.

Матрица устранения неполадок

СимптомВероятная причинаПроверка
Просмотрщик работает, но каждая страница имеет водяной знакЛицензия не была загружена, либо лицензия просрочена по календарюПолучите IDoconutLicenseService; проверьте каталог вывода и рабочий каталог процесса
AddDoconut() бросает исключение для плагинаЛицензия не предоставляет возможность этого плагинаПроверьте IsCapabilityGranted(...) и удалите регистрации, которые вы не покупали
Настроенный относительный путь работает локально, но не в IIS/контейнереРабочий каталог процесса изменилсяИспользуйте AppContext.BaseDirectory или абсолютный путь
Заменённый файл .lic не оказывает влиянияСинглтон сервис лицензий уже был созданПерезапустите приложение
OpenDocumentAsync бросает LicenseExceptionПодпись, домен, окно версии, черный список или проверка плагина во время выполнения отклонили лицензиюПрочитайте сообщение об исключении/отклонении, не раскрывая его недоверенным клиентам
Лицензия на отдельную возможность работала ранее, но сейчас нетСтарый код передавал явные пути к лицензии в конструктор ViewerПереместите сопутствующие файлы .lic рядом с Doconut.Viewer.lic и позвольте автообнаружению загрузить их

Следующие шаги

  • Лицензирование — возможности, уровни лицензий и проверка того, что было загружено во время выполнения.
  • Устранение неполадок — водяные знаки, отклонённые лицензии и ошибки возможностей.

Была ли эта страница полезной?