การตั้งค่าใบอนุญาต
ที่ที่ Doconut มองหาไฟล์ใบอนุญาตของคุณ
หากไม่มีใบอนุญาต Doconut ยังสามารถแสดงเอกสารได้ — แต่ทุกหน้าจะมีลายน้ำการประเมินผล หน้านี้อธิบายวิธีสี่วิธีในการจัดหาใบอนุญาต และลำดับความสำคัญที่แน่นอนเมื่อมีการตั้งค่ามากกว่าหนึ่งวิธี.
สี่วิธีในการจัดหาใบอนุญาต
มีทั้งหมดสี่วิธี: แหล่งที่มาชัดเจนสามแหล่งบน DoconutOptions — สตรีม, เนื้อหาดิบ, หรือเส้นทางไฟล์ — พร้อมกับการค้นหาอัตโนมัติเมื่อไม่มีการตั้งค่าใด ๆ เมื่อมีการตั้งค่ามากกว่าหนึ่งแหล่ง ลำดับความสำคัญจะเป็นดังนี้:
LicenseStream แซง LicenseContent แซง LicensePath แซงการค้นหาอัตโนมัติ.
โดยเส้นทาง
LicensePath จะถูกส่งไปยัง File.Exists ตามที่ระบุเสมอ เส้นทางสัมพัทธ์จะถูกแก้ไขโดยอ้างอิงจาก ไดเรกทอรีทำงานปัจจุบัน ของกระบวนการ — ไม่ใช่โฟลเดอร์โปรเจกต์ของคุณ และไม่ใช่โฟลเดอร์ที่ Program.cs อยู่ หากเส้นทางไม่สามารถแก้ไขได้ Doconut จะไม่โยนข้อผิดพลาดและ ไม่ กลับไปใช้การค้นหาอัตโนมัติ — มันจะโหลดไม่มีใบอนุญาตและตัวดูเอกสารจะแสดงลายน้ำ การค้นหาอัตโนมัติจะทำงานเฉพาะเมื่อไม่มีการตั้งค่า LicensePath, LicenseContent, หรือ LicenseStream
ควรใช้เส้นทางแบบเต็ม (เช่น สร้างจาก IWebHostEnvironment.WebRootPath หรือ AppContext.BaseDirectory) หรือข้าม LicensePath ไปเลยและพึ่งพาการค้นหาอัตโนมัติด้านล่าง.
builder.Services.AddDoconut(options =>
{
options.LicensePath = Path.Combine(AppContext.BaseDirectory, "Doconut.Viewer.lic");
});โดยสตรีม
LicenseStream จะถูกอ่านหนึ่งครั้งเมื่อตอนเริ่มต้น — มีประโยชน์เมื่อใบอนุญาตมาจากที่เก็บความลับแทนไฟล์บนดิสก์.
// Precedence: LicenseStream > LicenseContent > LicensePath > auto-search.
builder.Services.AddDoconut(options =>
{
options.LicenseStream = licenseStream;
});โดยเนื้อหา
LicenseContent รับข้อความใบอนุญาตโดยตรง — จากตัวแปรสภาพแวดล้อม, ฐานข้อมูล, หรือผู้จัดการความลับ:
// 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 จะค้นหาใบอนุญาตด้วยตนเอง:
// 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();ไดเรกทอรีที่ตรวจสอบตามลำดับและชื่อไฟล์ที่ค้นหาในแต่ละไดเรกทอรี:
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 นี้:
<Target Name="CopyLicensesToOutput" AfterTargets="Build">
<ItemGroup>
<DoconutLicenseFiles Include="$(MSBuildProjectDirectory)\wwwroot\*.lic" />
</ItemGroup>
<Copy SourceFiles="@(DoconutLicenseFiles)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
</Target>เก็บไฟล์
.licไว้ไน่นอกระบบควบคุมเวอร์ชัน — ปล่อยให้พร้อมกับแอป หรือฉีดใบอนุญาตผ่านLicenseContentหรือLicenseStreamจากที่เก็บความลับของคุณ.
สิ่งที่เกิดขึ้นเมื่อไม่มีใบอนุญาต
การไม่มีใบอนุญาตจะไม่ทำให้เกิดข้อผิดพลาด AddDoconut() จะสำเร็จ แอปจะเริ่มทำงาน และตัวดูเอกสารจะทำงาน — แต่ทุกหน้าจะมีลายน้ำการประเมินผลและไม่มีความสามารถเสริมใด ๆ ที่ได้รับการอนุญาต
ไฟล์ใบอนุญาตที่พบแต่ถูกปฏิเสธเป็นกรณีที่แตกต่างออกไป ลายเซ็นไม่ถูกต้อง, การดัดแปลง, การบล็อก, หรือการสร้างที่อยู่นอกช่วงเวอร์ชันของใบอนุญาตจะทำให้ OpenDocumentAsync โยน LicenseException พร้อมกับ License.RejectionMessage ใบอนุญาตที่หมดอายุตามปฏิทินและไม่มีข้อความปฏิเสธจะยังคงทำงานในโหมดลายน้ำ
ปลั๊กอินต้องการความสามารถ
การลงทะเบียนปลั๊กอินโดยไม่มีสิทธิ์ที่สอดคล้องกันเป็นกรณีที่แตกต่าง: สำหรับใบอนุญาตที่หายไป, ไฟล์ TRIAL เก่า, หรือใบอนุญาตที่ชำระแล้วแต่ไม่มีความสามารถนั้น AddDoconut() จะโยน InvalidOperationException ทำให้แอปไม่เริ่มทำงาน ตัวอย่างเช่น การลงทะเบียนปลั๊กอิน Converter โดยไม่มีใบอนุญาตที่ให้สิทธิ์ 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.ข้อความจะแจ้งวิธีแก้โดยตรง: หรือเอาเรียก options.AddPlugin<...>() สำหรับปลั๊กอินนั้นออก, หรือทำการติดตั้งใบอนุญาตที่ชำระแล้วหรือใบอนุญาต Temporary/Demo (NFR) ที่ยังใช้งานได้ซึ่งให้ความสามารถนั้น การลงทะเบียนแบบชั่วคราวจะได้รับอนุญาตให้คงอยู่หลังจากวันหมดอายุ เพื่อให้แอปที่ตั้งค่าไว้แล้วสามารถทำงานในโหมดลดคุณภาพได้ในขณะรันแทนที่จะพังเมื่อรีสตาร์ท; เมื่อหมดอายุ ความสามารถเหล่านั้นจะถูกยกเลิก
ตรวจสอบใบอนุญาตที่โหลด
ใช้ IDoconutLicenseService ซึ่งเป็นแหล่งความจริงเดียวกันที่ SDK ใช้ เพื่อเปิดเผย endpoint การวินิจฉัยที่ผ่านการตรวจสอบสิทธิ์หรือเพื่อควบคุมฟีเจอร์ฟล็อก อย่าเปิดเผยเนื้อหาใบอนุญาตหรือคีย์
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 | ลายเซ็น, โดเมน, ช่วงเวอร์ชัน, รายการดำเนินการบล็อก, หรือประตูรันไทม์ของปลั๊กอินปฏิเสธใบอนุญาต | อ่านข้อความข้อยกเว้น/การปฏิเสธโดยไม่เปิดเผยต่อไคลเอนต์ที่ไม่เชื่อถือ |
ขั้นตอนต่อไป
- การให้ใบอนุญาต — ความสามารถ, ระดับใบอนุญาต, และการตรวจสอบสิ่งที่โหลดในขณะทำงาน.
- การแก้ไขปัญหา — ลายน้ำ, ใบอนุญาตที่ถูกปฏิเสธ, และข้อผิดพลาดของความสามารถ.
หน้านี้เป็นประโยชน์หรือไม่?