การตั้งค่าใบอนุญาต

Where Doconut looks for your license file

หากไม่มีใบอนุญาต, Doconut ยังสามารถแสดงเอกสารได้ — แต่ทุกหน้าจะมีลายน้ำการประเมินผล หน้านี้อธิบายสี่วิธีในการจัดหาใบอนุญาตและลำดับความสำคัญที่แน่นอนเมื่อมีการตั้งค่ามากกว่าหนึ่งวิธี

สี่วิธีในการจัดหาใบอนุญาต

มีทั้งหมดสี่วิธี: แหล่งที่มาชัดเจนสามแหล่งบน DoconutOptions — สตรีม, เนื้อหาดิบ, หรือเส้นทางไฟล์ — พร้อมกับการค้นหาอัตโนมัติเมื่อไม่มีการตั้งค่าใด ๆ เมื่อมีการตั้งค่ามากกว่าหนึ่งแหล่ง ลำดับความสำคัญจะเป็นดังนี้:

LicenseStream แซง LicenseContent แซง LicensePath แซง auto-search.

ตามเส้นทาง

LicensePath ถูกส่งไปยัง File.Exists ตามที่ให้ไว้อย่างตรงไปตรงมา เส้นทางสัมพัทธ์จะถูกแก้ไขโดยอิงจาก current working directory ของกระบวนการ — ไม่ใช่โฟลเดอร์โปรเจกต์ของคุณ และไม่ใช่โฟลเดอร์ที่ไฟล์ 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 > auto-search.
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>
  <!-- Delete first, so renaming or removing a .lic in wwwroot also takes it out of the output. -->
  <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<...>() สำหรับปลั๊กอินนั้น, หรือการติดตั้งใบอนุญาตที่ชำระแล้วหรือใบอนุญาต Temporary/Demo (NFR) ที่ยังใช้งานได้ซึ่งให้ความสามารถดังกล่าว การลงทะเบียนแบบชั่วคราวจะได้รับอนุญาตให้คงอยู่หลังจากวันหมดอายุเพื่อให้แอปที่ตั้งค่าไว้แล้วสามารถทำงานในโหมดลดคุณสมบัติได้ในขณะรันแทนที่จะพังเมื่อรีสตาร์ท; เมื่อหมดอายุ ความสามารถของมันก็ยังถูกยกเลิก

ตรวจสอบใบอนุญาตที่โหลด

ใช้ IDoconutLicenseService ซึ่งเป็นแหล่งข้อมูลที่เชื่อถือได้เดียวกันที่ SDK ใช้ เพื่อเปิดเผย endpoint การวินิจฉัยที่ผ่านการรับรองหรือเพื่อควบคุมฟีเจอร์ฟลักส์ อย่าเปิดเผยเนื้อหาใบอนุญาตหรือคีย์

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 ที่แทนที่ไม่มีผลบริการใบอนุญาตแบบ singleton ถูกสร้างแล้วรีสตาร์ทแอปพลิเคชัน
OpenDocumentAsync โยน LicenseExceptionลายเซ็น, โดเมน, ช่วงเวอร์ชัน, รายการดำ, หรือประตูรันไทม์ของปลั๊กอินปฏิเสธใบอนุญาตอ่านข้อความข้อยกเว้น/การปฏิเสธโดยไม่เปิดเผยต่อไคลเอนต์ที่ไม่เชื่อถือ

ขั้นตอนต่อไป

  • การให้ใบอนุญาต — ความสามารถ, ระดับใบอนุญาต, และการตรวจสอบสิ่งที่โหลดในขณะรัน
  • การแก้ไขปัญหา — ลายน้ำ, ใบอนุญาตที่ถูกปฏิเสธ, และข้อผิดพลาดของความสามารถ

หน้านี้เป็นประโยชน์หรือไม่?