Configuración de Licencia

Dónde Doconut busca su archivo de licencia

Sin una licencia, Doconut aún renderiza documentos — cada página solo lleva una marca de agua de evaluación. Esta página cubre las cuatro formas de proporcionar una licencia, y la precedencia exacta cuando se establece más de una.

Cuatro formas de proporcionar una licencia

Hay cuatro: tres fuentes explícitas en DoconutOptions — un flujo, contenido sin procesar o una ruta de archivo — más el descubrimiento automático cuando ninguna está configurada. Cuando se establece más de una, la precedencia es exacta:

LicenseStream vence a LicenseContent vence a LicensePath vence a la búsqueda automática.

Por ruta

LicensePath se pasa a File.Exists tal como se proporciona. Una ruta relativa se resuelve contra el directorio de trabajo actual del proceso — no contra la carpeta de su proyecto, y no contra la carpeta donde vive Program.cs. Si la ruta no se resuelve, Doconut no lanza una excepción y no recurre a la búsqueda automática — simplemente no carga ninguna licencia y el visor muestra marcas de agua. La búsqueda automática solo se ejecuta cuando ninguno de LicensePath, LicenseContent o LicenseStream está configurado.

Prefiera una ruta absoluta (por ejemplo construida a partir de IWebHostEnvironment.WebRootPath o AppContext.BaseDirectory), o omita LicensePath por completo y confíe en el descubrimiento automático a continuación.

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

Por flujo

LicenseStream se lee una vez al iniciar — útil cuando la licencia proviene de un almacén secreto en lugar de un archivo en disco.

csharp
// Precedence: LicenseStream > LicenseContent > LicensePath > auto-search.
builder.Services.AddDoconut(options =>
{
    options.LicenseStream = licenseStream;
});

Por contenido

LicenseContent acepta el texto de la licencia directamente — de una variable de entorno, una base de datos o un gestor de secretos:

csharp
// 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") ?? "";
});

Descubrimiento automático

No configure ninguna de las tres fuentes explícitas, y Doconut buscará la licencia por sí mismo:

csharp
// 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();

Los directorios de búsqueda, en orden, y los nombres de archivo buscados en cada uno:

text
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

Copiar la licencia a su carpeta de salida

LicensePath, y la búsqueda automática con AppContext.BaseDirectory, ambos requieren que el archivo .lic exista junto a la aplicación compilada — no solo en su wwwroot de origen. La propia aplicación de prueba del SDK lo copia en cada compilación con este objetivo MSBuild:

xml
<Target Name="CopyLicensesToOutput" AfterTargets="Build">
  <ItemGroup>
    <DoconutLicenseFiles Include="$(MSBuildProjectDirectory)\wwwroot\*.lic" />
  </ItemGroup>
  <Copy SourceFiles="@(DoconutLicenseFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
</Target>

Mantenga los archivos .lic fuera del control de versiones — despliegue estos junto a la aplicación, o inyecte la licencia mediante LicenseContent o LicenseStream desde su almacén secreto.

Qué ocurre sin una licencia

Una licencia ausente no lanza una excepción. AddDoconut() tiene éxito, la aplicación se inicia y el visor se ejecuta — pero cada página lleva una marca de agua de evaluación y no se concede ninguna capacidad opcional.

Un archivo de licencia que se encuentra pero es rechazado es diferente. Una firma inválida, manipulación, inclusión en lista negra, o una compilación fuera del rango de versiones de la licencia hace que OpenDocumentAsync lance LicenseException con License.RejectionMessage. Una licencia caducada por calendario que no tiene mensaje de rechazo continúa en modo con marca de agua.

Los complementos necesitan capacidades

Registrar un complemento sin la autorización correspondiente es diferente: para una licencia ausente, un archivo TRIAL heredado, o una licencia paga sin esa capacidad, AddDoconut() lanza InvalidOperationException, por lo que la aplicación no se inicia. Por ejemplo, registrar el complemento Converter sin una licencia que conceda 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.

El mensaje le indica la solución directamente: elimine la llamada options.AddPlugin<...>() para ese complemento, o instale una licencia paga o una licencia Temporal/Demo (NFR) activa que conceda la capacidad. Las registraciones temporales pueden sobrevivir a su fecha de expiración para que una aplicación ya configurada pueda degradarse en tiempo de ejecución en lugar de fallar al reiniciar; una vez expiradas, sus capacidades siguen revocadas.

Verificar la licencia cargada

Utilice IDoconutLicenseService, la misma fuente de verdad usada por el SDK, para exponer un endpoint de diagnóstico autenticado o para controlar banderas de características. No devuelva contenidos ni claves de la licencia.

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
}));

La licencia se lee durante el registro de AddDoconut(). ResetLicense es actualmente una propiedad de compatibilidad sin una ruta de recarga activa, por lo que reemplazar un archivo de licencia requiere reiniciar la aplicación.

Matriz de solución de problemas

SíntomaCausa probableVerificación
El visor funciona pero cada página tiene marca de aguaNo se cargó ninguna licencia, o la licencia está caducada por calendarioResuelva IDoconutLicenseService; verifique el directorio de salida y el directorio de trabajo del proceso
AddDoconut() lanza una excepción para un complementoLa licencia no concede esa capacidad del complementoVerifique IsCapabilityGranted(...) y elimine las registraciones que no compró
Una ruta relativa configurada funciona localmente pero no en IIS/contenedorCambió el directorio de trabajo del procesoUse AppContext.BaseDirectory o una ruta absoluta
El archivo .lic reemplazado no tiene efectoEl servicio singleton de licencia ya estaba creadoReinicie la aplicación
OpenDocumentAsync lanza LicenseExceptionFirma, dominio, ventana de versión, lista negra o la puerta de tiempo de ejecución del complemento rechazaron la licenciaLea la excepción/mensaje de rechazo sin exponerlo a clientes no confiables

Próximos pasos

  • Licencias — capacidades, niveles de licencia y verificar lo que se cargó en tiempo de ejecución.
  • Solución de problemas — marcas de agua, licencias rechazadas y errores de capacidad.

¿Fue útil esta página?