הגדרת רישיון

היכן Doconut מחפש את קובץ הרישיון שלך

בלי רישיון, Doconut עדיין מציג מסמכים — כל דף מציג סימן מים של הערכה. דף זה מסביר את ארבעת הדרכים לספק רישיון, ואת סדר העדיפויות המדויק כאשר מוגדרים יותר מאחד.

הרישיון נטען פעם אחת, במהלך AddDoconut(). זה שינוי מהספרייה הקודמת של .NET Standard, שבה הרישיון נמסר למופע של Viewer או הוגדר דרך הקריאות הסטטיות Viewer.DoconutLicense(...) / Viewer.SetLicensePlugin(...). השיטות האלו אינן מנגנון אתחול בגרסה זו — ראה את מדריך ההגירה.

ארבע דרכים לספק רישיון

יש ארבע: שלושה מקורות מפורשים בDoconutOptions — זרם, תוכן גולמי, או נתיב קובץ — בנוסף לגילוי אוטומטי כאשר אף אחד מהם לא מוגדר. כאשר מוגדרים יותר מאחד, סדר העדיפויות הוא מדויק:

LicenseStream מנצח על LicenseContent מנצח על LicensePath מנצח על חיפוש אוטומטי.

לפי נתיב

LicensePath מועבר לFile.Exists בדיוק כפי שניתן. נתיב יחסי נפתר ביחס לספריית העבודה הנוכחית של התהליך — לא לתיקיית הפרויקט שלך, ולא לתיקייה שבה נמצא Program.cs. אם הנתיב אינו נפתר, Doconut לא זורק שגיאה ולא חוזר לחיפוש אוטומטי — הוא פשוט לא טוען רישיון והצופה מציג סימן מים. חיפוש אוטומטי פועל רק כאשר אף אחד מLicensePath, LicenseContent, או LicenseStream אינו מוגדר. קבצי הרישיון של כל תוסף באותה תיקייה (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 > חיפוש אוטומטי.
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, ועוד כל קובץ לפי יכולת
// קבצי 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-capability license, alongside the base license

שום דבר מחוץ לתיקייה wwwroot אינו נקרא: .lic בתיקיית הפלט עצמה, או בwwwroot/lib, מתעלמים ממנו.

אם בעבר העברת List<string> של נתיבי רישיון לבונה Viewer — אחד לכל יכולת — שמור קבצים נלווים אלה ליד Doconut.Viewer.lic ותן לגילוי האוטומטי לאסוף אותם. אין אפשרות של רשימת‑נתיבים בDoconutOptions.

העתק את הרישיון לתיקיית הפלט שלך

כאשר התהליך אינו רץ מתיקיית הפרויקט — אפליקציה שפורסמה, IIS, מכולה, רץ מבחן — הסקר הראשון נכשל, והשני, {AppContext.BaseDirectory}/wwwroot, חייב למצוא את הקובץ. אפליקציית הבדיקה של ה‑SDK מעתיקה את הרישיונות לשם בכל בנייה עם יעד MSBuild זה:

xml
<Target Name="CopyLicensesToOutput" AfterTargets="Build">
  <ItemGroup>
    <DoconutLicenseFiles Include="$(MSBuildProjectDirectory)\wwwroot\*.lic" />
    <StaleOutputLicenses Include="$(OutDir)wwwroot\*.lic" />
  </ItemGroup>
  <!-- מחק תחילה, כך ששינוי שם או הסרת קובץ .lic ב‑wwwroot גם יוציא אותו מהפלט. -->
  <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<...>() עבור תוסף זה, או להתקין רישיון בתשלום או רישיון זמני/הדגמה (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 שהוחלף אינו משפיעשירות הרישיון היחיד כבר נוצראתחל את האפליקציה
OpenDocumentAsync זורק LicenseExceptionחתימה, תחום, חלון גרסה, רשימה שחורה, או שער זמן ריצה של תוסף דחו את הרישיוןקרא את הודעת החריגה/דחייה מבלי לחשוף אותה ללקוחות לא מהימנים
רישיון לפי יכולת עבד בעבר אך לא כעתהקוד הישן העביר נתיבי רישיון מפורשים לבונה Viewerהעבר את קבצי .lic המלוויים ליד Doconut.Viewer.lic ותן לגילוי האוטומטי לטעון אותם

הצעדים הבאים

  • רישוי — יכולות, רמות רישוי, ואימות מה נטען בזמן הריצה.
  • פתרון בעיות — סימני מים, רישיונות נדחים, ושגיאות יכולת.

האם דף זה היה מועיל?