Настройка лицензии
Где Doconut ищет ваш файл лицензии
Без лицензии Doconut всё равно отображает документы — каждая страница просто содержит водяной знак оценки. Эта страница описывает четыре способа предоставления лицензии и точный порядок приоритета, когда задано более одного.
Четыре способа предоставления лицензии
Существует четыре: три явных источника в DoconutOptions — поток, сырое содержимое или путь к файлу — плюс автоматическое обнаружение, когда ни один из них не задан. Когда задано более одного, приоритет ясен:
LicenseStream побеждает LicenseContent, LicenseContent побеждает LicensePath, LicensePath побеждает авто‑поиск.
По пути
LicensePath передаётся в File.Exists точно так, как указано. Относительный путь разрешается относительно текущего рабочего каталога процесса — а не папки вашего проекта и не папки, где находится Program.cs. Если путь не разрешается, Doconut не бросает исключение и не переходит к авто‑поиску — он просто не загружает лицензию, и просмотрщик отображает водяные знаки. Авто‑поиск запускается только тогда, когда ни LicensePath, ни LicenseContent, ни LicenseStream не заданы.
Предпочтительно использовать абсолютный путь (например, построенный из IWebHostEnvironment.WebRootPath или AppContext.BaseDirectory), либо полностью опустить LicensePath и полагаться на автоматическое обнаружение ниже.
builder.Services.AddDoconut(options =>
{
options.LicensePath = Path.Combine(AppContext.BaseDirectory, "Doconut.Viewer.lic");
});По потоку
LicenseStream читается один раз при запуске — удобно, когда лицензия берётся из хранилища секретов, а не из файла на диске.
// Precedence: LicenseStream > LicenseContent > LicensePath > auto-search.
builder.Services.AddDoconut(options =>
{
options.LicenseStream = licenseStream;
});По содержимому
LicenseContent принимает сам текст лицензии — из переменной окружения, базы данных или менеджера секретов:
// License XML from a database, environment variable, or secret manager —
// no file on disk. Beaten only by LicenseStream.
builder.Services.AddDoconut(options =>
{
options.LicenseContent = Environment.GetEnvironmentVariable("DOCONUT_LICENSE") ?? "";
});Автоматическое обнаружение
Не задавайте ни один из трёх явных источников, и Doconut самостоятельно ищет лицензию:
// Configure nothing, and Doconut searches for the license itself:
// 1. {CurrentDirectory}/wwwroot
// 2. {CurrentDirectory}/wwwroot/lib
// 3. AppContext.BaseDirectory (the build output folder)
// It looks for Doconut.Viewer.lic plus any per-plugin
// Doconut.Viewer.<Capability>.lic files alongside it.
builder.Services.AddDoconut();Пробные каталоги в порядке проверки и имена файлов, которые ищутся в каждом из них:
1. {CurrentDirectory}/wwwroot
2. {CurrentDirectory}/wwwroot/lib
3. AppContext.BaseDirectory
Filenames (checked in each directory above, in order):
Doconut.Viewer.lic — base viewer license
Doconut.Viewer.<Capability>.lic — per-plugin license, alongside Doconut.Viewer.licСкопируйте лицензию в папку вывода
LicensePath и пробный каталог AppContext.BaseDirectory авто‑поиска оба требуют, чтобы файл .lic находился рядом со скомпилированным приложением — а не только в исходном wwwroot. Тестовое приложение SDK копирует его при каждой сборке с помощью этой цели MSBuild:
<Target Name="CopyLicensesToOutput" AfterTargets="Build">
<ItemGroup>
<DoconutLicenseFiles Include="$(MSBuildProjectDirectory)\wwwroot\*.lic" />
</ItemGroup>
<Copy SourceFiles="@(DoconutLicenseFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
</Target>Держите файлы
.licвне системы контроля версий — размещайте их рядом с приложением или внедряйте лицензию черезLicenseContentилиLicenseStreamиз вашего хранилища секретов.
Что происходит без лицензии
Отсутствующая лицензия не вызывает исключения. AddDoconut() успешно выполняется, приложение запускается, и просмотрщик работает — но каждая страница имеет водяной знак оценки, и никакие дополнительные возможности не предоставляются.
Файл лицензии, который найден, но отклонён, — это другое дело. Неправильная подпись, вмешательство, занесение в чёрный список или сборка вне временного окна лицензии вызывают выброс LicenseException из OpenDocumentAsync с 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, чтобы открыть аутентифицированный диагностический эндпоинт или управлять флагами функций. Не возвращайте содержимое лицензии или ключи.
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 в настоящее время является совместимым свойством без активного пути перезагрузки, поэтому замена файла лицензии требует перезапуска приложения.
Матрица устранения неполадок
| Симптом | Вероятная причина | Проверка |
|---|---|---|
| Viewer работает, но каждая страница имеет водяной знак | Лицензия не была загружена, либо лицензия просрочена по календарю | Получите IDoconutLicenseService; проверьте каталог вывода и рабочий каталог процесса |
AddDoconut() бросает исключение для плагина | Лицензия не предоставляет возможность этого плагина | Проверьте IsCapabilityGranted(...) и удалите регистрации, которые вы не покупали |
| Настроенный относительный путь работает локально, но не в IIS/контейнере | Рабочий каталог процесса изменился | Используйте AppContext.BaseDirectory или абсолютный путь |
Заменённый файл .lic не оказывает влияния | Сервис лицензии‑singleton уже был создан | Перезапустите приложение |
OpenDocumentAsync бросает LicenseException | Подпись, домен, окно версии, черный список или проверка плагина отклонили лицензию | Прочитайте сообщение об исключении/отклонении, не раскрывая его недоверенным клиентам |
Следующие шаги
- Лицензирование — возможности, уровни лицензий и проверка того, что было загружено во время выполнения.
- Устранение неполадок — водяные знаки, отклонённые лицензии и ошибки возможностей.
Была ли эта страница полезной?