Configuración de Licencia
Dónde Doconut busca su archivo de licencia
Sin una licencia, Doconut sigue renderizando 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.
La licencia se carga una vez, durante AddDoconut(). Eso es un cambio respecto a la biblioteca .NET Standard anterior, donde la licencia se entregaba a una instancia Viewer o se configuraba mediante las llamadas estáticas Viewer.DoconutLicense(...) / Viewer.SetLicensePlugin(...). Esos métodos no son un mecanismo de inicio en esta versión — vea la guía de migración.
Cuatro formas de proporcionar una licencia
Hay cuatro: tres fuentes explícitas en DoconutOptions — un flujo, contenido crudo o una ruta de archivo — más el descubrimiento automático cuando ninguna de ellas está configurada. Cuando se establece más de una, la precedencia es exacta:
LicenseStream supera a LicenseContent supera a LicensePath supera a búsqueda automática.
Por ruta
LicensePath se pasa a File.Exists exactamente como se da. Una ruta relativa se resuelve contra el directorio de trabajo actual del proceso — no la carpeta de tu proyecto, y no 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. Los archivos de licencia por complemento en la misma carpeta (Doconut.Viewer.<Capability>.lic) se leen con ella, de modo que LicensePath y AddPlugin<...>() funcionan juntos cuando las licencias de los complementos están junto a la licencia base.
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.
builder.Services.AddDoconut(options =>
{
options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "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.
// Prioridad: LicenseStream > LicenseContent > LicensePath > búsqueda automática.
builder.Services.AddDoconut(options =>
{
options.LicenseStream = licenseStream;
});Por contenido
LicenseContent acepta el propio texto de la licencia — de una variable de entorno, una base de datos o un gestor de secretos:
// XML de licencia desde una base de datos, variable de entorno o gestor de secretos —
// no hay archivo en disco. Solo superado por 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:
// No configure nada, y Doconut busca la licencia por sí mismo, solo en estas dos carpetas:
// 1. {CurrentDirectory}/wwwroot
// 2. {AppContext.BaseDirectory}/wwwroot (wwwroot dentro de la carpeta de salida de compilación)
// Busca Doconut.lic primero, luego Doconut.Viewer.lic, más cualquier archivo por capacidad
// Doconut.Viewer.<Capability>.lic files alongside it.
builder.Services.AddDoconut();Las carpetas de inspección, en orden, y los nombres de archivo buscados en cada una:
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 licenseNada fuera de una carpeta wwwroot se lee: un .lic en la propia carpeta de salida, o en wwwroot/lib, se ignora.
Si previamente pasó un List<string> de rutas de licencia al constructor Viewer — uno por capacidad — mantenga esos archivos complementarios junto a Doconut.Viewer.lic y permita que el descubrimiento automático los recoja. No hay una opción de lista de rutas en DoconutOptions.
Copiar la licencia a su carpeta de salida
Cuando el proceso no se ejecuta desde la carpeta del proyecto — una aplicación publicada, IIS, un contenedor, un ejecutor de pruebas — la primera búsqueda falla, y la segunda, {AppContext.BaseDirectory}/wwwroot, tiene que encontrar el archivo. La propia aplicación de prueba del SDK copia las licencias allí en cada compilación con este objetivo de MSBuild:
<Target Name="CopyLicensesToOutput" AfterTargets="Build">
<ItemGroup>
<DoconutLicenseFiles Include="$(MSBuildProjectDirectory)\wwwroot\*.lic" />
<StaleOutputLicenses Include="$(OutDir)wwwroot\*.lic" />
</ItemGroup>
<!-- Eliminar primero, de modo que renombrar o eliminar un .lic en wwwroot también lo elimine de la salida. -->
<Delete Files="@(StaleOutputLicenses)" />
<Copy SourceFiles="@(DoconutLicenseFiles)" DestinationFolder="$(OutDir)wwwroot" />
</Target>El destino debe ser $(OutDir)wwwroot: un .lic copiado a la raíz de salida nunca es encontrado por la búsqueda automática. Los ejemplos LicensePath en esta página apuntan al mismo lugar.
Mantenga los archivos
.licfuera del control de versiones — desplieguelos junto a la aplicación, o inyecte la licencia a través deLicenseContentoLicenseStreamdesde su almacén secreto.
Qué ocurre sin una licencia
Una licencia faltante 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 faltante, un archivo legado TRIAL, o una licencia pagada 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:
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 pagada 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 durante el reinicio; una vez expiradas, sus capacidades siguen revocadas.
Verificar la licencia cargada
Utilice IDoconutLicenseService, la misma fuente de referencia usada por el SDK, para exponer un punto de diagnóstico autenticado o para controlar banderas de características. No devuelva el contenido de la licencia ni las claves.
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 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íntoma | Causa probable | Verificación |
|---|---|---|
| El visor funciona pero cada página tiene marca de agua | No se cargó ninguna licencia, o la licencia está caducada por calendario | Resuelva IDoconutLicenseService; verifique el directorio de salida y el directorio de trabajo del proceso |
AddDoconut() lanza una excepción para un complemento | La licencia no concede esa capacidad del complemento | Verifique IsCapabilityGranted(...) y elimine las registraciones que no compró |
| Una ruta relativa configurada funciona localmente pero no en IIS/contenedor | Cambió el directorio de trabajo del proceso | Use AppContext.BaseDirectory o una ruta absoluta |
El archivo .lic reemplazado no tiene efecto | El servicio singleton de licencia ya estaba creado | Reinicie la aplicación |
OpenDocumentAsync lanza LicenseException | Firma, dominio, ventana de versión, lista negra, o puerta de tiempo de ejecución del complemento rechazó la licencia | Lea el mensaje de excepción/rechazo sin exponerlo a clientes no confiables |
| Una licencia por capacidad funcionó antes pero ahora no | El código antiguo pasaba rutas de licencia explícitas al constructor Viewer | Mueva los archivos .lic acompañantes junto a Doconut.Viewer.lic y permita que el descubrimiento automático los cargue |
Próximos pasos
- Licencias — capacidades, niveles de licencia y la verificación de lo que se cargó en tiempo de ejecución.
- Resolución de problemas — marcas de agua, licencias rechazadas y errores de capacidad.
¿Fue útil esta página?