การตั้งค่าไลเซนส์
ที่ที่ Doconut ค้นหาไฟล์ไลเซนส์ของคุณ
หากไม่มีไลเซนส์, Doconut ยังสามารถแสดงเอกสารได้ — แต่ทุกหน้าจะมีลายน้ำการประเมินผลอยู่. หน้านี้อธิบายวิธีสี่วิธีในการจัดหาไลเซนส์, และลำดับความสำคัญที่แน่นอนเมื่อมีการตั้งค่ามากกว่าหนึ่งวิธี.
สี่วิธีในการจัดหาไลเซนส์
มีทั้งหมดสี่วิธี: แหล่งที่มาชัดเจนสามแหล่งบน DoconutOptions — สตรีม, เนื้อหาดิบ, หรือเส้นทางไฟล์ — พร้อมกับการค้นหาอัตโนมัติเมื่อไม่มีการตั้งค่าใด ๆ. เมื่อมีการตั้งค่ามากกว่าหนึ่งแหล่ง, ลำดับความสำคัญจะเป็นดังนี้:
LicenseStream ชนะ LicenseContent ชนะ LicensePath ชนะ auto-search.
ตามเส้นทาง
LicensePath จะถูกส่งไปยัง File.Exists ตามที่กำหนดไว้โดยตรง. เส้นทางสัมพันธ์จะถูกแก้ไขโดยอ้างอิงกับ ไดเรกทอรีทำงานปัจจุบัน ของกระบวนการ — ไม่ใช่โฟลเดอร์โปรเจกต์ของคุณ, และไม่ใช่โฟลเดอร์ที่ Program.cs อยู่. หากเส้นทางไม่สามารถแก้ไขได้, Doconut จะไม่โยนข้อผิดพลาดและ ไม่ กลับไปใช้การค้นหาอัตโนมัติ — มันจะเพียงแค่ไม่โหลดไลเซนส์และตัวดูจะแสดงลายน้ำ. การค้นหาอัตโนมัติจะทำงานเฉพาะเมื่อไม่มีการตั้งค่า LicensePath, LicenseContent, หรือ LicenseStream. ไฟล์ไลเซนส์ per-plugin ในโฟลเดอร์เดียวกัน (Doconut.Viewer.<Capability>.lic) จะถูกอ่านพร้อมกับมัน, ดังนั้น LicensePath และ AddPlugin<...>() จะทำงานร่วมกันเมื่อไลเซนส์ของปลั๊กอินอยู่ข้าง ๆ ไลเซนส์หลัก.
ควรใช้เส้นทางแบบเต็ม (เช่น สร้างจาก IWebHostEnvironment.WebRootPath หรือ AppContext.BaseDirectory), หรือข้ามการตั้งค่า LicensePath ทั้งหมดและพึ่งพาการค้นหาอัตโนมัติด้านล่าง.
builder.Services.AddDoconut(options =>
{
options.LicensePath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "Doconut.Viewer.lic");
});ตามสตรีม
LicenseStream จะถูกอ่านหนึ่งครั้งเมื่อเริ่มต้น — มีประโยชน์เมื่อไลเซนส์มาจากที่เก็บความลับแทนไฟล์บนดิสก์.
// ความสำคัญ: LicenseStream > LicenseContent > LicensePath > auto-search.
builder.Services.AddDoconut(options =>
{
options.LicenseStream = licenseStream;
});ตามเนื้อหา
LicenseContent รับข้อความไลเซนส์โดยตรง — จากตัวแปรสภาพแวดล้อม, ฐานข้อมูล, หรือผู้จัดการความลับ:
// License XML จากฐานข้อมูล, ตัวแปรสภาพแวดล้อม, หรือผู้จัดการความลับ —
// ไม่มีไฟล์บนดิสก์. ถูกเอาชนะได้เฉพาะโดย LicenseStream.
builder.Services.AddDoconut(options =>
{
options.LicenseContent = Environment.GetEnvironmentVariable("DOCONUT_LICENSE") ?? "";
});การค้นหาอัตโนมัติ
ไม่กำหนดค่าใด ๆ, แล้ว Doconut จะค้นหาไลเซนส์ด้วยตนเอง, ในสองโฟลเดอร์นี้เท่านั้น:
// ไม่กำหนดค่าใด ๆ, และ Doconut ค้นหาไลเซนส์ด้วยตนเอง, ในสองโฟลเดอร์นี้เท่านั้น:
// 1. {CurrentDirectory}/wwwroot
// 2. {AppContext.BaseDirectory}/wwwroot (wwwroot ภายในโฟลเดอร์ผลลัพธ์ของการสร้าง)
// มันมองหา Doconut.lic ก่อน, จากนั้น Doconut.Viewer.lic, พร้อมกับไลเซนส์ per-plugin ใด ๆ
// ไฟล์ Doconut.Viewer.<Capability>.lic ที่อยู่ข้าง ๆ
builder.Services.AddDoconut();โฟลเดอร์ที่ตรวจสอบ, ตามลำดับ, และชื่อไฟล์ที่ค้นหาในแต่ละโฟลเดอร์:
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 นี้:
<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:
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 | ลายเซ็น, โดเมน, ช่วงเวอร์ชัน, รายการดำเนินการห้าม, หรือประตูรันไทม์ของปลั๊กอินปฏิเสธใบอนุญาต | อ่านข้อความข้อยกเว้น/การปฏิเสธโดยไม่เปิดเผยต่อไคลเอนต์ที่ไม่เชื่อถือ |
ขั้นตอนต่อไป
- การให้ใบอนุญาต — ความสามารถ, ระดับใบอนุญาต, และการตรวจสอบสิ่งที่โหลดในขณะทำงาน.
- การแก้ไขปัญหา — ลายน้ำ, ใบอนุญาตที่ถูกปฏิเสธ, และข้อผิดพลาดของความสามารถ.
หน้านี้เป็นประโยชน์หรือไม่?