Настройка лицензии
Где 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 и полагаться на автоматическое обнаружение ниже.
builder.Services.AddDoconut(options =>
{
options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
});По потоку
LicenseStream читается один раз при запуске — полезно, когда лицензия берётся из хранилища секретов, а не из файла на диске.
// Приоритет: LicenseStream > LicenseContent > LicensePath > авто-поиск.
builder.Services.AddDoconut(options =>
{
options.LicenseStream = licenseStream;
});По содержимому
LicenseContent принимает сам текст лицензии — из переменной окружения, базы данных или менеджера секретов:
// XML лицензии из базы данных, переменной окружения или менеджера секретов —
// нет файла на диске. Превосходит только LicenseStream.
builder.Services.AddDoconut(options =>
{
options.LicenseContent = Environment.GetEnvironmentVariable("DOCONUT_LICENSE") ?? "";
});Автоматическое обнаружение
Не настраивая ни один из трёх явных источников, Doconut ищет лицензию самостоятельно:
// Не настраивая ничего, Doconut ищет лицензию самостоятельно, только в этих двух папках:
// 1. {CurrentDirectory}/wwwroot
// 2. {AppContext.BaseDirectory}/wwwroot (wwwroot внутри папки вывода сборки)
// Он ищет Doconut.lic первым, затем Doconut.Viewer.lic, а также любые per-capability
// файлы Doconut.Viewer.<Capability>.lic рядом с ним.
builder.Services.AddDoconut();Папки для проверки, в порядке следования, и имена файлов, которые ищутся в каждой:
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:
<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:
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 или управлять флагами функций. Не возвращайте содержимое лицензии или ключи.
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 и позвольте автообнаружению загрузить их |
Следующие шаги
- Лицензирование — возможности, уровни лицензий и проверка того, что было загружено во время выполнения.
- Устранение неполадок — водяные знаки, отклонённые лицензии и ошибки возможностей.
Была ли эта страница полезной?