라이선스 설정

Doconut이 라이선스 파일을 찾는 위치

라이선스가 없으면 Doconut은 여전히 문서를 렌더링하지만 — 모든 페이지에 평가 워터마크가 표시됩니다. 이 페이지에서는 라이선스를 제공하는 네 가지 방법과 둘 이상이 설정된 경우 정확한 우선순위를 다룹니다.

라이선스를 제공하는 네 가지 방법

DoconutOptions에 있는 세 가지 명시적 소스(스트림, 원시 내용, 파일 경로)와 설정되지 않았을 때 자동 검색을 포함하여 네 가지가 있습니다. 둘 이상이 설정된 경우, 우선순위는 정확히 다음과 같습니다:

LicenseStream > LicenseContent > LicensePath > 자동 검색

경로별

LicensePath는 주어진 그대로 File.Exists에 전달됩니다. 상대 경로는 프로세스의 현재 작업 디렉터리를 기준으로 해석되며 — 프로젝트 폴더가 아니고, Program.cs 파일이 위치한 폴더도 아닙니다. 경로가 해석되지 않으면 Doconut은 예외를 발생시키지 않으며 자동 검색으로 되돌아가지도 않습니다 — 단순히 라이선스를 로드하지 않고 뷰어에 워터마크를 표시합니다. 자동 검색은 LicensePath, LicenseContent, LicenseStream 중 어느 것도 설정되지 않았을 때만 실행됩니다.

절대 경로를 사용하는 것이 좋습니다(예: IWebHostEnvironment.WebRootPath 또는 AppContext.BaseDirectory에서 구성). 또는 LicensePath를 완전히 생략하고 아래의 자동 검색에 의존할 수 있습니다.

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

스트림별

LicenseStream은 시작 시 한 번 읽히며 — 라이선스가 디스크 파일이 아닌 비밀 저장소에서 제공될 때 유용합니다.

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

내용별

LicenseContent는 라이선스 텍스트 자체를 받아들입니다 — 환경 변수, 데이터베이스, 또는 비밀 관리자에서 가져올 수 있습니다:

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

자동 검색

세 가지 명시적 소스 중 어느 것도 구성하지 않으면 Doconut이 스스로 라이선스를 검색합니다:

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

검색 디렉터리 순서와 각 디렉터리에서 찾는 파일 이름은 다음과 같습니다:

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

라이선스를 출력 폴더에 복사하기

LicensePath와 자동 검색의 AppContext.BaseDirectory 탐색 모두, 빌드된 앱 옆에 .lic 파일이 존재해야 합니다 — 소스 wwwroot에만 있으면 안 됩니다. SDK 자체 테스트 앱은 매 빌드 시 다음 MSBuild 타깃으로 파일을 복사합니다:

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

.lic 파일을 소스 제어에 포함하지 마세요 — 앱과 함께 배포하거나 비밀 저장소에서 LicenseContent 또는 LicenseStream을 통해 라이선스를 주입하세요.

라이선스가 없을 때 발생하는 일

라이선스가 없다고 예외가 발생하지는 않습니다. AddDoconut()가 성공하고 앱이 시작되며 뷰어가 실행되지만 — 모든 페이지에 평가 워터마크가 표시되고 선택적 기능이 부여되지 않습니다.

찾았지만 거부된 라이선스 파일은 상황이 다릅니다. 서명 오류, 변조, 블랙리스트, 또는 라이선스 버전 기간 외의 빌드가 OpenDocumentAsyncLicenseExceptionLicense.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 파일이 효과가 없음싱글톤 라이선스 서비스가 이미 생성됨애플리케이션을 재시작하십시오
OpenDocumentAsyncLicenseException을 발생서명, 도메인, 버전 기간, 블랙리스트, 또는 플러그인 런타임 게이트가 라이선스를 거부함예외/거부 메시지를 읽되 신뢰할 수 없는 클라이언트에 노출하지 마십시오

다음 단계

  • 라이선스 — 기능, 라이선스 등급, 그리고 런타임에 로드된 내용을 확인합니다.
  • 문제 해결 — 워터마크, 거부된 라이선스, 그리고 기능 오류.

이 페이지가 도움이 되었나요?