Налаштування ліцензії

Where Doconut looks for your license file

Без ліцензії Doconut все одно відображає документи — кожна сторінка лише містить водяний знак оцінки. Ця сторінка описує чотири способи надання ліцензії та точний порядок пріоритету, коли встановлено більше одного.

Чотири способи надання ліцензії

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

LicenseStream перевершує LicenseContent перевершує LicensePath перевершує авто-пошук.

За шляхом

LicensePath передається до File.Exists точно так, як вказано. Відносний шлях розв'язується щодо поточної робочої директорії процесу — а не вашої папки проєкту, і не папки, в якій знаходиться Program.cs. Якщо шлях не розв'язується, Doconut не генерує помилку і не переходить до авто-пошуку — він просто не завантажує ліцензію, і переглядач додає водяний знак. Авто-пошук запускається лише коли жоден з LicensePath, LicenseContent або LicenseStream не встановлений. Файли ліцензій per-plugin у тій самій папці (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
// License 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-plugin
// 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-plugin license, alongside the base license

Нічого поза папкою wwwroot не читається: .lic у самій вихідній папці або у wwwroot/lib ігнорується.

Скопіюйте ліцензію у вашу вихідну папку

Коли процес не запускається з папки проєкту — опублікованого застосунку, 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, щоб надати автентифіковану діагностичну кінцеву точку або керувати прапорцями функцій. Не повертайте вміст ліцензії чи ключі.

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Підпис, домен, часове вікно версії, чорний список або ворота виконання плагіна відхилили ліцензіюПрочитайте повідомлення про виключення/відхилення, не розкриваючи його недовіреним клієнтам

Наступні кроки

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

Чи була ця сторінка корисною?