איך פועלת תאימות אפליקציות Windows ── שמירה על אפליקציות ישנות עם מצב תאימות, shims ו-Compatibility Administrator
· Go Komura · Windows, מצב תאימות, Shims, תאימות אפליקציות, Compatibility Administrator, שימוש חוזר בנכסים ישנים, פיתוח Windows, מערכות קיימות
«אפליקציה עסקית בת עשר שנים שקוד המקור שלה נעלם לא מתחילה במחשב Windows 11 חדש. סימנתי ‘Windows XP’ בלשונית התאימות בתיבת המאפיינים והיא פשוט עבדה. — מה זה בעצם עושה? מותר להמשיך להסתמך על זה?» זו ייעוץ שאנחנו שומעים לעיתים קרובות.
כשתיבת סימון אחת גורמת למשהו לעבוד, טבעי להרגיש אי-נוחות. הזהות האמיתית של מצב התאימות, שנראה כמו קסם, היא אוסף פיסות קוד קטנות שנקראות shims שיושבות בין האפליקציה ל-Windows API ומחזירות «שקר». Windows עצמו משתמש בתחליף הזמני הזה בהיקף גדול כדי להשאיר אפליקציות מדורות רבים רצות, וחושף חלק מהמנגנון למשתמשים ולמנהלים.
בשימוש בלי להבין את המנגנון, הארכת חיים הופכת ל«אסור לגעת כי אנחנו לא יודעים למה זה עובד» לא יציבה. הבינו את המנגנון ותוכלו להחליט, עם נימוקים, עד כמה אפשר להסתמך בבטחה, מה ישבור את זה, ומתי צריך לשכתב.
flowchart TB
accTitle: הבנת המנגנון משנה את איכות הארכת החיים
accDescr: שימוש במצב תאימות בלי להבין את המנגנון מוביל להארכת חיים לא יציבה שאין מעזים לגעת בה; הבנת המנגנון מאפשרת החלטה מנומקת עד כמה אפשר להסתמך מה ישבור ומתי לשכתב
unknown["שימוש בלי להבין את המנגנון"] --> fear["הארכת חיים לא יציבה שאין מעזים לגעת"]
known["שימוש אחרי הבנת המנגנון"] --> judge["החלטות עם נימוקים"]
judge -.-> j1["עד כמה אפשר להסתמך"]
judge -.-> j2["מה ישבור את זה"]
judge -.-> j3["מתי צריך לשכתב"]
איור 1: גם לאותה הארכת חיים האיכות שונה בין חרדה מאי-ידיעת המנגנון לבין החלטה המבוססת על הבנתו.
מיועד לאנשי IT בעסקים קטנים ובינוניים ולמפתחי אפליקציות Windows שמטפלים באפליקציות עסקיות ישנות, המאמר הזה מסדר, ממקורות ראשוניים של Microsoft Learn, את מנגנון ה-shim שהוא הזהות האמיתית של מצב התאימות, מה יכולים ה-shims היציגים, איך להחיל אותם ארגונית עם Compatibility Administrator, הגבולות ש-shim אינו מציל, ואיך להחליט בין הארכת חיים להגירה.
1. השורה התחתונה קודם
- הזהות האמיתית של מצב התאימות היא shims (שכבת תאימות). הגדרות מלשונית התאימות נכתבות אל
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers, וצרור shims מוחל על התהליך בהתחלה.12 - Shim הוא וו API במצב משתמש שכותב מחדש את טבלת כתובות הייבוא (IAT). הוא מיירט את הנתיב שבו האפליקציה קוראת לממשקי Windows ומחזיר את אותן תשובות שהיה מחזיר Windows ישן. הוא אינו משנה את מערכת ההפעלה עצמה.3
- מה ש-shim יכול לעשות הוא אותו טווח שתיקון קוד באפליקציה יכול לעשות. הוא אינו יכול לעקוף מנגנוני אבטחה, ואינו יכול לתקן בעיות במצב ליבה (מנהלי התקנים).3
- מיקרוסופט שולחת מספר גדול של shims מוכנים — שקרי גרסה, מיפוי מחדש של נתיבי קבצים, זיוף רישום, זיוף בדיקות מנהל ועוד. אפשר להחיל אותם על קובצי EXE בודדים מ-Compatibility Administrator.4
- Windows עצמו משתמש ב-shims כברירת מחדל. מסד התאימות הסטנדרטי של מערכת ההפעלה (.sdb) מותאם בכל השקה, ו-PCA (Program Compatibility Assistant) יכול גם לזהות בעיה ולהחיל הגדרת תאימות אוטומטית.15
- «לענות כאילו זה Windows ישן יותר» הוא כעת ברירת המחדל. מ-Windows 8.1 ואילך
GetVersionExאינו מחזיר גרסת מערכת שהאפליקציה לא הכריזה במנשר. מצב תאימות הוא הרחבה של אותו מנגנון.67 - Shims אינם עובדים על אפליקציות 16 סיביות, תלות במנהל ליבה או גישה ישירה לחומרה. במיוחד, אפליקציות 16 סיביות אינן יכולות לרוץ כלל על Windows של 64 סיביות.8
- לאפליקציות ש«דורשות מנהל אבל אינן צריכות אותו באמת», RunAsInvoker הוא הצעד הסטנדרטי.
__COMPAT_LAYER=RunAsInvokerמדכא את בקשת ההעלאה ומשאיר את האפליקציה רצה בהרשאות רגילות.9 - ריצה תחת shim פירושה שאפשר להאריך חיים לעת עתה, אבל הנתיב האמיתי הוא «להריץ בלי shim». אם מחליטים להאריך חיים, רושמים אילו shims גורמים לה לרוץ ומנהלים זאת כחומר להחלטת שכתוב.
2. התמונה הגדולה של תאימות אפליקציות — שכבות התאימות לאחור שכבר יש ל-Windows
לפני שנדבר על shims, הנה רשימת המנגנונים שכבר יש ל-Windows לאפליקציות ישנות. גם כשאנשים אומרים «התחיל לעבוד במצב תאימות», מה שבאמת מציל את האפליקציה הוא אחת מהשכבות האלה, או שילוב של כמה.
| שכבה | מה היא עושה | יעד טיפוסי |
|---|---|---|
| Shims (מצב תאימות) | מיירטים קריאות API ומזייפים את אותן תגובות ש-Windows ישן היה נותן | אפליקציות שנכתבו מול מערכת ישנה יותר בכלל |
| וירטואליזציית UAC (קבצים / רישום) | מפנים כתיבות אל HKLM\Software או Program Files שחסרות הרשאה אל VirtualStore לכל משתמש |
אפליקציות 32 סיביות שנכתבו בהנחת הרשאות מנהל |
| WOW64 | מריץ אפליקציות 32 סיביות כמות שהן על Windows של 64 סיביות (מספק תצוגות 32 סיביות של הרישום ומערכת הקבצים) | אפליקציות 32 סיביות בכלל |
| וירטואליזציית DPI | גורם לאפליקציה שאינה מודעת ל-DPI לצייר ב-96 DPI ומציג אותה במתיחת מפת הסיביות | אפליקציות ישנות על צגים עם DPI גבוה |
וירטואליזציית UAC היא אמצעי מעבר שחל על תהליכים אינטראקטיביים 32 סיביות בלי מנשר, ומיקרוסופט עצמה קובעת שזו «טכנולוגיה זמנית שאנחנו מתכוונים להסיר מגרסת Windows עתידית».10 הנזק האמיתי מהפניית Wow6432Node ומה-VirtualStore, ואיך להתמודד איתו, מכוסה בפירוט ב«Registry 32-bit/64-bit Redirection and Virtualization Pitfalls»; המאמר הזה משאיר shims במרכז ומזכיר את השכבות האחרות רק עד כמה שנדרש.
flowchart TB
accTitle: איפה יושבת וירטואליזציית UAC
accDescr: וירטואליזציית UAC היא אמצעי מעבר לתהליכים אינטראקטיביים 32 סיביות בלי מנשר; היא מפנה כתיבות אל VirtualStore לכל משתמש אבל מיקרוסופט עצמה אומרת שזו טכנולוגיה זמנית המיועדת להסרה מ-Windows עתידי
proc["תהליך אינטראקטיבי 32 סיביות בלי מנשר"] --> uacv["וירטואליזציית UAC חלה"]
uacv --> vs["מופנה אל VirtualStore לכל משתמש"]
uacv -.-> tmp["טכנולוגיה זמנית המיועדת להסרה בהמשך"]
איור 2: וירטואליזציית UAC היא אמצעי מעבר לתהליכי 32 סיביות בלי מנשר, ואי אפשר להסתמך עליה לצמיתות.
הערת צד על וירטואליזציית DPI: אפליקציה שלא הכריזה מודעות DPI מטופלת כאילו היא מציירת ב-96 DPI (100%), ו-Windows מוחחת את מפת הסיביות לתצוגה. לכן אפליקציות ישנות נראות «מטושטשות» על צג עם DPI גבוה, ו«עקוף התנהגות קנה-מידה של DPI גבוה» בלשונית התאימות הוא המתג שמשנה את התנהגות הווירטואליזציה הזו.11
flowchart TB
accTitle: איך פועלת וירטואליזציית DPI
accDescr: אפליקציה שלא הכריזה מודעות DPI מטופלת כמציירת ב-96 DPI; Windows מוחחת את מפת הסיביות כך שהיא נראית מטושטשת ועקיפת הגדרות DPI גבוה בלשונית התאימות מחליפה את התנהגות הווירטואליזציה
app["אפליקציה שאינה מכריזה מודעות DPI"] --> treat["מטופלת כמציירת ב-96 DPI"]
treat --> stretch["מפת הסיביות נמתחת לתצוגה"]
stretch --> blur["נראית מטושטשת על צג DPI גבוה"]
tab["עקוף התנהגות קנה-מידה של DPI גבוה"] -.->|מחליף את התנהגות הווירטואליזציה| treat
איור 3: אפליקציה שאינה מודעת ל-DPI מטופלת כ-96 DPI ונמתחת; העקיפה בלשונית התאימות היא המתג של הווירטואליזציה הזו.
3. מה באמת shim — יירוט בין ממשקים בכתיבה מחדש של ה-IAT
3.1. ה«מתורגמן» שעומד בין האפליקציה למערכת ההפעלה
קובץ הפעלה של Windows (פורמט PE) קורא לממשקים ב-DLL חיצוניים דרך טבלת כתובות הייבוא (IAT). כשהאפליקציה קוראת ל-GetVersionEx היא רק קופצת לכתובת הכתובה ב-IAT. מנגנון ה-shim מנצל זאת. בזמן טעינה הוא כותב מחדש את רשומת ה-IAT של הממשק היעד לכתובת קוד ה-shim ומכניס את עצמו בין האפליקציה ל-Windows. ממשקים שמתקבלים דינמית דרך GetProcAddress מטופלים בווי על GetProcAddress עצמו.3
אחרי היירוט, shim עשוי להחזיר מספר גרסה ישן ל«מה גרסת מערכת ההפעלה הנוכחית?», או למפות מחדש גישת קובץ למיקום שאינו ניתן לכתיבה למקום אחר, ואז לקרוא לממשק האמיתי אם צריך. מנקודת מבט האפליקציה נראה כאילו «רצה על Windows ישן»; מנקודת מבט מערכת ההפעלה נראה כאילו «אפליקציה מנומסת רצה» — ה-shim הוא המתורגמן בין השניים.
flowchart TB
accTitle: הנתיב שבו shim מיירט קריאת API
accDescr: קריאת API של האפליקציה עוברת דרך ה-IAT; כתיבה מחדש של רשומת ה-IAT אל ה-shim בטעינה מאפשרת יירוט זיוף אותה תגובה ש-Windows ישן היה נותן ואז קריאה לממשק האמיתי אם צריך
app["אפליקציה"] -->|קריאת API| iat["רשומת IAT"]
iat -->|נכתבת מחדש אל ה-shim בטעינה| shim["Shim (מתורגמן)"]
shim -->|אם צריך| api["ממשק Windows האמיתי"]
shim -.-> lie["מזייף את אותה תגובה ש-Windows ישן היה נותן"]
gpa["קריאות דרך GetProcAddress"] -.->|מטופלות בווי| shim
איור 4: Shim מיירט בין האפליקציה לממשק Windows. מה שנכתב מחדש הוא ה-IAT בצד האפליקציה; מערכת ההפעלה עצמה אינה משתנה.
שלוש תכונות חשובות נובעות מהעיצוב הזה.3
- Shim רץ כקוד בצד האפליקציה. הוא אינו חלק ממערכת ההפעלה, ולכן כפוף לאותן מגבלות אבטחה כמו האפליקציה. Shim אינו יכול לעקוף את מנגנוני האבטחה של מערכת ההפעלה, ואין צורך להרפות הגדרות אבטחה כדי להשתמש ב-shim.
- מה ש-shim יכול לתקן, תיקון קוד בצד האפליקציה יכול גם לתקן. Shim הוא תחליף למקרים של «אין מקור / אי אפשר לתקן»; הוא אינו חזק יותר מתיקון קוד.
- מצב משתמש בלבד. בעיות תאימות במנהלי התקנים שרצים במצב ליבה אי אפשר לתקן ב-shim.
3.2. מסד ה-shim (.sdb) וההתאמה
טבלת ההתאמה «איזה shim להחיל על איזה EXE» היא מסד ה-shim, קובץ בינארי עם סיומת .sdb. קובצי ההפעלה של האפליקציה היעד נרשמים במסד לפי תכונות כמו שם קובץ, גודל, סכום ביקורת וגרסה (תכונות התאמה), ומותאמים בהתחלת התהליך. התרופות כוללות Appfix (shim) שמזריק וו API, ו-Apphelp שמציג הודעת «לאפליקציה הזו יש בעיית תאימות». צרור של כמה shims ודגלים הוא שכבת תאימות (מצב תאימות).1
קל להחמיץ: ההתאמה הזו רצה לא רק על אפליקציות שיש להן מצב תאימות מוגדר, אלא בכל השקת תהליך. Windows שולח מסד סטנדרטי של מערכת ההפעלה עם תיקונים לאלפי אפליקציות ידועות (הקבצים חיים תחת %WINDIR%\AppPatch), ובמחשב שלכם היום כמעט בוודאי אפליקציה ישנה כלשהי מתחילה עם shim מחובר בלי שאף אחד שם לב. תיקוני תאימות שמיקרוסופט מספקת נשלחים כחלק מ-Windows ומתעדכנים דרך Windows Update.3
flowchart TB
accTitle: התאמת מסד ה-shim בהתחלת תהליך
accDescr: כל השקת תהליך מותאמת מול מסד ה-shim; אם רישום תואם את תכונות ההתאמה Appfix מזריק shim או Apphelp מציג הודעה אחרת התהליך מתחיל כמות שהוא
start["התחלת תהליך"] --> db["התאמה מול .sdb"]
db -.-> attr["שם קובץ גודל וכו"]
db --> hit{"רישום?"}
hit -->|כן| appfix["Appfix: הזרקת shim"]
hit -->|כן| apphelp["Apphelp: הודעה"]
hit -->|לא| plain["התחל כמות שהוא"]
layer["שכבת תאימות"] -.->|צרור shims ודגלים| appfix
איור 5: ההתאמה רצה בכל השקת תהליך, לא רק על אפליקציות שיש להן מצב תאימות מוגדר.
3.3. PCA — המנגנון שמחיל shims אוטומטית
נתיב נוסף שבו יכול shim להיות מוחל בלי שמנהל התכוון לכך הוא PCA (Program Compatibility Assistant). PCA צופה בביצוע אפליקציה, וכשהוא מזהה סימנים לבעיית תאימות ידועה הוא מציע למשתמש להחיל תיקון או, במקרים מסוימים, מחיל הגדרת תאימות אוטומטית. למשל אפליקציה שקורסת בקריאה לקוד בתוך DLL ששוחרר מקבלת PINDLL, ואפליקציה שנכשלת בכתיבה לקובץ Windows מוגן מקבלת WRPMITIGATION.5
flowchart TB
accTitle: איך PCA מחיל הגדרת תאימות אוטומטית
accDescr: PCA צופה בביצוע אפליקציה וכשהוא מזהה סימנים לבעיית תאימות ידועה מציע למשתמש להחיל תיקון או במקרים מסוימים מחיל הגדרת תאימות אוטומטית
run["ביצוע אפליקציה"] --> pca["PCA צופה"]
pca --> sign{"סימנים לבעיה ידועה?"}
sign -->|כן| resp{"איזה מקרה?"}
resp -->|מטופל בהצעה| suggest["הצע החלת תיקון"]
resp -->|מקרים מסוימים| auto["החל הגדרת תאימות אוטומטית"]
sign -->|לא| none["הרץ כמות שהוא"]
auto -.-> ex["דוגמה: PINDLL או WRPMITIGATION"]
איור 6: PCA צופה בביצוע אפליקציה, וכשהוא מזהה סימנים לבעיה ידועה מציע תיקון או מחיל אותו אוטומטית.
הזהות של «מעולם לא הגדרתי כלום, אבל בשלב כלשהו תיבת מצב התאימות הייתה מסומנת» היא במקרים רבים זה. זה אינו תקלה ואינו לחיצה שגויה; זה Windows מתנהג כפי שתוכנן.
4. מה יכולים ה-shims היציגים
מתוך ה-shims המוכנים שמיקרוסופט מפרסמת, הנה מבחר שעולה לעיתים קרובות בפועל כשמרחיבים חיים של אפליקציה עסקית.4
| Shim | מה הוא יכול (סיכום) |
|---|---|
| WinXPSP3VersionLie ומשפחת VersionLie | להחזיר גרסה ישנה יותר שצוינה לשאילתות גרסת מערכת (זיוף גרסה) |
| CorrectFilePaths | למפות מחדש גישה לנתיב קובץ שאינו ניתן לכתיבה או שאינו קיים למקום אחר |
| VirtualRegistry | להפנות או לזייף קריאות וכתיבות רישום (כולל זיוף גרסה וזיוף מפתחות שאינם קיימים) |
| ForceAdminAccess | להחזיר זמנית True לבדיקת «האם אתה חבר בקבוצת המנהלים?» |
| RunAsAdmin / RunAsHighest / RunAsInvoker | לתת מבחוץ רמת ביצוע השקולה ל-requireAdministrator / highestAvailable / asInvoker במנשר |
| WRPMitigation | לזייף הצלחה לכתיבות לקובצי מערכת מוגנים ולמפתחות רישום כדי שהאפליקציה תוכל להמשיך |
| EmulateGetDiskFreeSpace | לדווח על שטח דיסק פנוי כמקסימום 2GB (לאפליקציות שגולשות בדיסקים גדולים) |
| GlobalMemoryStatusLie | לזייף את ערכי מצב הזיכרון המדווחים (לאפליקציות שנכשלות בבדיקת זיכרון בהתחלה) |
| LoadLibraryRedirect | לטעון את ה-DLL הנוכחי של Windows במקום DLL מערכת ישן שהאפליקציה שולחת |
בהסתכלות על הרשימה, רוב ה-shims הם «שקר שמחזיר את התשובה שהאפליקציה הישנה מצפה לה». הדיסק לכל היותר 2GB, מערכת ההפעלה היא XP, אתה מנהל — הם יוצרים מחדש, בתוך אותו תהליך בלבד, את תמונת העולם של התקופה שבה נולדה האפליקציה.
זיוף גרסה הפך ל«התנהגות ברירת מחדל רשמית»
זיוף גרסה אינו האק מיוחד. מ-Windows 8.1 ואילך הערך ש-GetVersionEx מחזיר תלוי במנשר האפליקציה. אפליקציה בלי הכרזת <supportedOS> במדור <compatibility> של המנשר מקבלת תמיד שווה-ערך ל-Windows 8 (6.2), יהא אשר יהא מערכת ההפעלה בפועל. כשיש הכרזה מוחזר הערך עד מערכת ההפעלה הגבוהה ביותר שהוכרזה (למשל אם הכרזתם עד ה-GUID של Windows 8.1 תקבלו 6.3 גם ב-Windows 11).67
אז «גרסת Windows שהאפליקציה רואה» נקבעת בשלבים המוערמים האלה.
- מוחזר הערך עד מערכת ההפעלה שהוכרזה במנשר (6.2 אם אין הכרזה)
- אם מוחל מצב תאימות (shim ממשפחת VersionLie), מוחזרת גרסת מערכת ההפעלה שנבחרה6
flowchart TB
accTitle: איך נקבעת גרסת מערכת ההפעלה שהאפליקציה רואה
accDescr: הערך ש-GetVersionEx מחזיר נקבע לפי הכרזת supportedOS במנשר; בלי הכרזה מוחזר 6.2 שווה-ערך ל-Windows 8 עם הכרזה מוחזר הערך עד מערכת ההפעלה הגבוהה ביותר ואם מוחל shim ממשפחת VersionLie הוא נדרס בגרסת מערכת ההפעלה שנבחרה
q["שאילתת GetVersionEx"] --> m{"יש הכרזת supportedOS?"}
m -->|לא| v62["מוחזר שווה-ערך Windows 8 (6.2)"]
m -->|כן| decl["ערך עד מערכת ההפעלה הגבוהה שהוכרזה"]
v62 --> lie{"הוחל shim ממשפחת VersionLie?"}
decl --> lie
lie -->|כן| fake["ערך מערכת ההפעלה שנבחר במצב תאימות"]
lie -->|לא| asis["הערך מוחזר כמות שהוא"]
איור 7: גרסת Windows שהאפליקציה רואה נקבעת בשלבים מוערמים לפי המנשר ולפי shims.
אם אפליקציה פנימית «מתפצלת לפי גרסת מערכת ההפעלה, ובאופן מבלבל נשפטת כ-8 אף שזה Windows 11», חשדו קודם בהכרזת supportedOS במנשר. להפך, אפליקציה ישנה שמסרבת להתחיל על סמך בדיקת גרסה יכולה, בהסתברות גבוהה, לעבור עם shim ממשפחת VersionLie. במקרים רבים היא רק מסתכלת על מספר הגרסה, וההתנהגות בפועל תקינה על מערכת חדשה יותר.
flowchart TB
accTitle: שני תסמינים שנגרמים מגרסה ואיך לטפל
accDescr: אם אפליקציה פנימית נשפטת כ-8 אף שזה Windows 11 חשדו בהכרזת supportedOS במנשר; אפליקציה ישנה שמסרבת להתחיל בבדיקת גרסה יכולה לעבור בהסתברות גבוהה עם VersionLie
sym1["נשפטת כ-8 אף שזה Windows 11"] --> fix1["חשדו בהכרזת supportedOS"]
sym2["סירוב התחלה בבדיקת גרסה"] --> fix2["נסו לעבור עם VersionLie"]
fix2 -.-> why["ההתנהגות בפועל לעיתים קרובות תקינה על מערכת חדשה"]
איור 8: כשהשיפוט מיושן חשדו במנשר; כשההתחלה מסורבת חשדו ב-VersionLie.
5. מה עושה תיבת הסימון של מצב התאימות
הגדרות ממאפיינים → לשונית התאימות מאוחסנות במפתח הרישום AppCompatFlags\Layers. הגדרות תאימות אפליקציות DXGI וכדומה משתמשות באותו מפתח כמקום לציין שכבת תאימות.2 בואו נסתכל בפועל.
reg query "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
ל-EXE שעליו הגדרתם «Windows XP (Service Pack 3)», «הפעל תוכנית זו כמנהל» ו«עקוף התנהגות קנה-מידה של DPI גבוה» בלשונית התאימות תראו ערך כמו הבא.
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
C:\LegacyApp\Gyomu.exe REG_SZ ~ WINXPSP3 RUNASADMIN HIGHDPIAWARE
התאמות יציגות בין פריטי התיבה לערכים (אושרו ב-Windows 11; שמות פריטים וערכים יכולים להשתנות לפי גרסת מערכת ההפעלה).
| פריט לשונית התאימות | ערך שנכתב (דוגמה) | מה זה באמת |
|---|---|---|
| מצב תאימות: Windows XP (Service Pack 3) | WINXPSP3 | שכבת תאימות שמצררת זיוף גרסה וכמה shims אחרים |
| מצב צבע מופחת (8 סיביות / 256 צבעים) | 256COLOR | הקלה למצב הצבע הישן |
| הרצה ברזולוציית מסך 640 × 480 | 640X480 | הרצה ברזולוציה נמוכה |
| השבת אופטימיזציות מסך מלא | DISABLEDXMAXIMIZEDWINDOWEDMODE | השבת אופטימיזציות ציור במסך מלא |
| עקוף התנהגות קנה-מידה של DPI גבוה (אפליקציה) | HIGHDPIAWARE | עצור וירטואליזציית DPI (מתיחת מפת סיביות)11 |
| הפעל תוכנית זו כמנהל | RUNASADMIN | בקש העלאה בהתחלה |
שלוש נקודות לשמור.
- «הפעל תוכנית זו כמנהל» נכתב באותו מקום. מצב תאימות ודגל ההעלאה חיים יחד באותו מפתח Layers, ומשם נולדת הבלבול «הגדרתי מצב תאימות והעלאה הגיעה / נעלמה». הסתכלות ישירה בערך מפרידה בין השניים.
- מה שנכתב ב-HKCU הוא «הגדרת אותו משתמש». אם מגדירים מלשונית «שנה הגדרות לכל המשתמשים», זה נכתב למפתח בעל אותו שם בצד HKLM וחל על כל המשתמשים. כשמפיצים בדימוי היו מודעים לאיזה צד כותבים.
- התיבה היא רק הכניסה לשכבות המוכנות. הלשונית מאפשרת לבחור שכבות יציגות בלבד; אי אפשר לבחור shims בודדים ולשלב אותם. זה מה ש-Compatibility Administrator בפרק הבא עושה.
flowchart TB
accTitle: הנתיב מהגדרת לשונית התאימות עד לתוקף
accDescr: הגדרות לשונית התאימות מאוחסנות כנתיב EXE וערך במפתח Layers של AppCompatFlags; בפעם הבאה שה-EXE מתחיל הטוען קורא את הערך ומחיל את שכבת התאימות המתאימה על התהליך
tab["הגדרה בלשונית התאימות"] --> reg["אחסון נתיב EXE והערך במפתח Layers"]
reg --> boot["התחלת EXE הבאה"]
boot --> loader["הטוען קורא את הערך"]
loader --> apply["החלת שכבת התאימות על התהליך"]
reg -.-> hkcu["HKCU לאותו משתמש בלבד"]
reg -.-> hklm["HKLM חל על כל המשתמשים"]
איור 9: התיבה במציאות היא כתיבה למפתח Layers, וההחלה קורה בהתחלה הבאה.
6. Compatibility Administrator בפועל — בניית .sdb מותאם והפצתו
6.1. איך משיגים אותו, והסתייגויות
Compatibility Administrator הוא כלי הכלול ב-Windows ADK (Windows Assessment and Deployment Kit).12 אחרי התקנה קיימות מהדורות 32 סיביות ו-64 סיביות, וחייבים להשתמש במהדורת 32 סיביות לאפליקציות 32 סיביות ובמהדורת 64 סיביות לאפליקציות 64 סיביות.13
יש הסתייגות חשובה נוספת. אם מתחילים את Compatibility Administrator מוגבה (כמנהל) ובודקים, וירטואליזציית UAC והפניה אינן מתנהגות כפי שהיו מתנהגות למשתמש אמיתי, ואפשר לשפוט בטעות ש«זה תוקן». תמיד אשרו את אפקט התיקון באותו חשבון ובהרשאות כמו המשתמש בפועל.4
flowchart TB
accTitle: שתי הסתייגויות בשימוש ב-Compatibility Administrator
accDescr: השתמשו במהדורת 32 סיביות לאפליקציות 32 סיביות ובמהדורת 64 סיביות לאפליקציות 64 סיביות ואשרו את אפקט התיקון באותו חשבון והרשאות כמו המשתמש בפועל לא במצב מוגבה
app32["אפליקציית 32 סיביות"] --> tool32["השתמשו במהדורת 32 סיביות"]
app64["אפליקציית 64 סיביות"] --> tool64["השתמשו במהדורת 64 סיביות"]
elev["בדיקה במצב מוגבה"] -.-> wrong["עלולים לשפוט תיקון בטעות"]
user["בדיקה בהרשאות המשתמש בפועל"] --> ok["אשרו את האפקט"]
איור 10: בחירת מהדורת 32 או 64 סיביות, ואישור באותן הרשאות כמו המשתמש בפועל, הן הסתייגויות הכניסה.
6.2. הליך בניית מסד תאימות מותאם
הקווים הכלליים כדלקמן.14
- בחלונית השמאלית של Compatibility Administrator צרו מסד חדש תחת «Custom Databases» ובחרו «Create New» → «Application Fix»
- הזינו את שם האפליקציה ושם הספק, וציינו את קובץ ה-EXE היעד
- בחרו את מצב התאימות (השכבה) להחלה — ניסיון צרור כמו «תאימות Windows XP» קודם הוא הנתיב הקצר
- אם צריך, הוסיפו תיקוני תאימות בודדים (shims) — אפשר לצמצם לסט מינימלי כמו VersionLie בלבד או CorrectFilePaths בלבד
- אשרו את תנאי ההתאמה (גודל קובץ, סכום ביקורת, גרסה וכן הלאה) ושמרו
תנאי ההתאמה הם המפתח ל«החל זאת רק על ה-EXE הזה». תנאי היסוד ברירת המחדל מספיקים בדרך כלל, אבל אנחנו ממליצים להשאיר תנאי שיכול לזהות את גרסת האפליקציה. זה מונע את התאונה ששקר ישן ממשיך לחול על גרסה חדשה כשהספק שולח אחר כך מהדורה מתוקנת.1415
flowchart TB
accTitle: הליך בניית מסד תאימות מותאם
accDescr: צרו Application Fix במסד חדש ציינו שם אפליקציה ו-EXE יעד נסו קודם צרור מצב תאימות ואז צמצמו ל-shims בודדים אם צריך אשרו תנאי התאמה ושמרו
new["יצירת מסד חדש"] --> fix["בחירת Application Fix"]
fix --> info["ציון שם האפליקציה וה-EXE היעד"]
info --> layer["ניסיון צרור מצב תאימות"]
layer --> single["אם צריך צמצום ל-shims בודדים"]
single --> match["אישור תנאי התאמה ושמירה"]
match -.-> ver["השארת תנאי שמזהה את הגרסה"]
איור 11: ל-Application Fix נסו קודם צרור מצב תאימות, צמצמו לסט מינימלי, והגבילו את היעד בתנאי התאמה.
בדקו את ה-.sdb שיצרתם קודם במכונת אימות. ברגע שהוא עובד כמתוכנן מגלגלים אותו לארגון.
6.3. הפצה עם sdbinst
הפקודה שמחילה .sdb מותאם על כל מחשב היא sdbinst.exe (דורשת הרשאות מנהל).15
:: Install (-q is silent with no confirmation)
sdbinst -q "C:\Deploy\MyCorpFixes.sdb"
:: Uninstall (by file)
sdbinst -q -u "C:\Deploy\MyCorpFixes.sdb"
:: Uninstall (by database GUID)
sdbinst -q -u -g {database GUID}
כאסטרטגיית פריסה ארגונית מיקרוסופט ממליצה לגבש למסד מותאם אחד ברמת החברה (או המחלקה) ולנהל אותו מרכזית, במקום לשלוח .sdb נפרד עם המתקין של כל אפליקציה. ככל שיש יותר תיקונים קל יותר לעדכן ולהפיץ מחדש מסד אחד מאשר להפיץ מסדי שורה אחת רבים. למסד מותאם יש GUID משלו, והתקנת גרסה חדשה עם אותו GUID מחליפה אוטומטית את הגרסה הישנה, כך שגם פעולות עדכון נשארות פשוטות. שימו את ההפצה עצמה על נתיב קיים שיכול לרוץ בהרשאות מנהל, כמו אריזה כ-MSI או סקריפט אתחול.15
flowchart TB
accTitle: הנתיב מיצירת .sdb מותאם עד הפצתו
accDescr: צרו מסד תאימות מותאם ב-Compatibility Administrator בדקו במכונת אימות החילו על כל מחשב עם sdbinst ובעדכון התקינו גרסה חדשה עם אותו GUID כך שהישנה מוחלפת אוטומטית
make["יצירה ב-Compatibility Administrator"] --> test["בדיקה במכונת אימות"]
test --> deploy["החלה על כל מחשב עם sdbinst"]
deploy --> update["התקנת גרסה חדשה עם אותו GUID"]
update -.-> replace["הגרסה הישנה מוחלפת אוטומטית"]
deploy -.-> inv["רישום בתוכניות ותכונות"]
איור 12: .sdb מותאם מגולגל דרך יצירה, אימות והפצת sdbinst, ועדכונים מנוהלים לפי GUID.
מסד מותאם מותקן נרשם כפריט ב«תוכניות ותכונות (אפליקציות מותקנות)», כך שאפשר גם לאשר מלאי והסרה משם. אילו מחשבים נושאים איזה .sdb הוא מידע ששייך לפנקס ניהול הנכסים.
7. מקרים שבהם זה לא עובד, והגבולות
Shims אינם כדור כסף. לפי העיצוב הם אינם עובדים במקרים הבאים.
- בעיות מצב ליבה. Shim רץ בתוך תהליך מצב משתמש, ולכן אי-תאימות של מנהל התקן אי אפשר לתקן. אם מנהל ההתקן של מכשיר מדידה ישן, דונגל USB או מדפסת אינו תומך ב-Windows 11, שום דבר שתחיל בצד האפליקציה לא יפתור זאת. קוד שרץ בליבה, כמו חלקים מתוכנת אנטי-וירוס, אותו דבר.3
- אפליקציות 16 סיביות. Windows של 64 סיביות אינו תומך בהרצת אפליקציות 16 סיביות. לידיות יש 32 סיביות תקפות ב-Windows של 64 סיביות ואי אפשר לקטוע אותן כדי להעביר לאפליקציית 16 סיביות, ולכן ההתחלה נכשלת עם
ERROR_BAD_EXE_FORMAT.8 גם כשהאפליקציה עצמה היא 32 סיביות קיימות חבילות מאותה תקופה שקדם-ההתקנה שלהן הוא 16 סיביות, והן מופיעות כ«האפליקציה הייתה רצה, אבל אי אפשר להתקין אותה». - גישה ישירה לחומרה. אפליקציות תעשייתיות שמניחות שהן יכולות לגעת ביציאות קלט/פלט או בזיכרון פיזי ישירות אינן מורשות לעשות זאת ממצב משתמש ב-Windows מודרני מלכתחילה, וזה מעבר לטווח ש-shim יכול לזייף.
- עקיפת מנגנוני אבטחה. כי shim רץ תחת אותן מגבלות אבטחה כמו האפליקציה, הוא אינו יכול להפוך «משהו שאי אפשר לעשות מחוסר הרשאה» לאפשרי. ForceAdminAccess ו-WRPMitigation רק מזייפים הצלחה של בדיקה או כתיבה כדי שהאפליקציה תוכל להמשיך; הם אינם כותבים מחדש בפועל משאב מוגן.34
- אפליקציות שבודקות את שלמותן בעצמן. אפליקציות עם הגנת העתקה ישנה או זיהוי חבלה יכולות לטפל בוו ה-API עצמו כחריג ולהפסיק לעבוד.
flowchart TB
accTitle: מקרים שבהם shim אינו עובד
accDescr: Shim רץ בתוך תהליך מצב משתמש ולכן אינו עובד על בעיות מנהל ליבה אפליקציות 16 סיביות גישה ישירה לחומרה או עקיפת מנגנוני אבטחה
shim["Shim (רץ במצב משתמש)"] -->|אינו עובד| drv["מנהל ליבה"]
shim -->|אינו עובד| b16["אפליקציית 16 סיביות"]
shim -->|אינו עובד| hw["גישה ישירה לחומרה"]
shim -->|אינו עובד| sec["עקיפת מנגנוני אבטחה"]
b16 -.-> fmt["ב-64 סיביות ההתחלה עצמה נכשלת"]
sec -.-> fake["רק מזייף הצלחה כדי שהאפליקציה תמשיך"]
איור 13: Shim הוא מצב משתמש בלבד ואינו מגיע לליבה, לאפליקציות 16 סיביות, לגישה ישירה לחומרה או לעקיפת אבטחה.
והגבול המהותי המשותף לכל shim הוא שהוא תחליף זמני. Shim הוא שקר המותאם לשימוש מסוים בממשק מסוים, ואם המימוש בצד מערכת ההפעלה משתנה ההנחה קורסת. Shims שמיקרוסופט מספקת מתוחזקים כחלק מ-Windows דרך Windows Update,3 אבל הטיפול בשקרים שהחלתם במסד מותאם הוא עבודת הארגון שלכם. תקצבו, כעלות הארכת חיים, פעולה שמוודאת את «רשימת האפליקציות המוחזקות בחיים על ידי shims» בכל עדכון תכונות.
flowchart TB
accTitle: Shims כתחליף זמני ומי אחראי לתחזוקתם
accDescr: Shim הוא שקר המותאם לשימוש ממשק מסוים וההנחה קורסת אם המימוש בצד מערכת ההפעלה משתנה; shims של מיקרוסופט מתוחזקים דרך Windows Update אבל הטיפול בשקרי מסד מותאם הוא עבודת הארגון ואימות בכל עדכון תכונות הוא עלות הארכת חיים
shim["Shim = שקר תחליף זמני"] --> break["שינוי מערכת ההפעלה שובר אותו"]
ms["Shims של מיקרוסופט"] --> wu["דרך Windows Update"]
own["שקרים של מסד מותאם"] --> self["הארגון מטפל בהם"]
self --> cost["אימות בכל עדכון הוא עלות הארכת חיים"]
איור 14: האחריות לתחזוקת שקר ה-shim מחולקת בין הסט שמיקרוסופט מספקת לסט המותאם של הארגון שלכם.
8. הערך המעשי של RunAsInvoker — להשתיק רק את בקשת ההעלאה
בין ה-shims, זה שעולה ביותר בעבודת IT יומיומית הוא RunAsInvoker.
אפליקציות עסקיות ישנות מסוימות מכריזות requireAdministrator במנשר, או מזוהות בטעות כמתקין משם ה-EXE או מתוכנו, ומבקשות העלאת UAC בכל התחלה. רבות מהן, עם זאת, רק מבקשות מנהל מאינרציה של עידן XP ואינן משתמשות בהרשאות מנהל באמת. החלת shim של RunAsInvoker דורסת גם זיהוי מתקין וגם מנשר, והאפליקציה מתחילה עם האסימון שעבר בירושה מתהליך האב (= הרשאות משתמש רגיל).9
flowchart TB
accTitle: איך RunAsInvoker מדכא בקשת העלאה
accDescr: הכרזת requireAdministrator במנשר או זיהוי שגוי כמתקין גורמים לבקשת העלאת UAC בהתחלה אבל החלת RunAsInvoker דורסת את שניהם והאפליקציה מתחילה עם אסימון תהליך האב
manifest["הכרזת requireAdministrator"] --> shim{"הוחל RunAsInvoker?"}
detect["זוהה בטעות כמתקין"] --> shim
shim -->|לא| uac["בקשת העלאת UAC בכל התחלה"]
shim -->|כן| token["מתחיל עם אסימון האב"]
token -.-> limit["עבודה שבאמת צריכה מנהל נכשלת בתוך האפליקציה"]
איור 15: RunAsInvoker רק דורס את סיבת בקשת ההעלאה; ההרשאות אינן גדלות.
גם בלי לבנות .sdb ב-Compatibility Administrator אפשר להחיל את אותה שכבה זמנית עם משתנה הסביבה __COMPAT_LAYER.
:: Apply RunAsInvoker to child processes started from this command prompt
set __COMPAT_LAYER=RunAsInvoker
start "" "C:\LegacyApp\Gyomu.exe"
# In PowerShell
$env:__COMPAT_LAYER = 'RunAsInvoker'
Start-Process 'C:\LegacyApp\Gyomu.exe'
אם הופכים את שני השורות האלה לקובץ אצווה ומפיצים אותו כקיצור דרך, אפשר להימנע ממסירת הרשאות מנהל מקומי למשתמשים רגילים, ו-IT כבר אינו נקרא בכל פעם לסיסמת UAC. זו טכניקת תאימות שמקשיחה את ההגנה, בהתאם להרשאה המינימלית.
flowchart TB
accTitle: האפקט של הפצת אצוות RunAsInvoker
accDescr: הפצת אצווה בת שתי שורות שמגדירה RunAsInvoker כקיצור דרך פירושה הימנעות ממסירת הרשאות מנהל למשתמשים רגילים אי-קריאה ל-IT לסיסמת UAC ותפעול שעוקב אחרי הרשאה מינימלית
bat["הפיצו אצווה בת שתי שורות"] --> noadmin["אפשר להימנע ממסירת הרשאות מנהל"]
bat --> nocall["IT אינו נקרא בגלל UAC"]
noadmin --> lp["תפעול שעוקב אחרי הרשאה מינימלית"]
nocall --> lp
איור 16: הפצת אצווה לבדה יכולה להפחית גם מסירת הרשאות מנהל וגם קריאה בגלל UAC.
גם ההסתייגויות, בבירור.
- ההרשאות אינן גדלות. עבודה שבאמת צריכה הרשאות מנהל (כתיבות ל-HKLM, עדכונים תחת Program Files וכן הלאה) תיכשל בתוך האפליקציה, או, אם התנאים מתקיימים, תופנה אל ה-VirtualStore על ידי וירטואליזציית UAC.10 אם שמירת הגדרות «הפסיקה לעבוד» פתאום, חשדו בווירטואליזציה.
- שיטת משתנה הסביבה חלה רק על תהליכי בן. להחלה קבועה, הגדרה ישירה במפתח Layers (ל-RUNASINVOKER אין פריט בלשונית) או הפצה דרך .sdb אמינה.
- תיקון יעד הכתיבה הוא הנתיב האמיתי. אם אפשר לשנות את האפליקציה, העבירו את קובץ ההגדרות תחת
%APPDATA%והכריזוasInvokerבמנשר — זו הצורה הנכונה.9
flowchart TB
accTitle: החלה זמנית וקבועה של RunAsInvoker
accDescr: החלה דרך משתנה COMPAT_LAYER חלה רק על תהליכי בן שמתחילים משם; להחלה קבועה השתמשו בהגדרה ישירה במפתח Layers או בהפצה דרך .sdb
env["הגדרה דרך משתנה סביבה"] --> child["חלה רק על תהליכי בן"]
child -.-> tmp["החלה זמנית"]
layers["הגדרה ישירה במפתח Layers"] --> always["החלה קבועה"]
sdb["הפצה דרך sdb"] --> always
איור 17: שיטת משתנה הסביבה היא החלה זמנית המוגבלת לתהליכי בן; הפיכתה אחת קבועה נעשית במפתח Layers או ב-.sdb.
9. ההחלטה בין הארכת חיים להגירה — מה לחשוב אחרי שזה עובד תחת shim
הרגע שבו זה עובד תחת shim הוא הקלה, אבל חשוב לא לעצור את החשיבה שם. עבודה תחת shim פירושה רק שזה במקרה התאים לכלי קיבול ש-Windows הכין. צירי ההחלטה, בטבלה.
| ציר החלטה | תנאים שנוטים להארכת חיים (shim) | תנאים שנוטים להגירה / שכתוב |
|---|---|---|
| תקופת שימוש נותרת | מתוכנן לפרוש עם העסק תוך 1–2 שנים | מונח להמשיך 5 שנים או יותר |
| קוד מקור | אין (הספק נעלם, או אבד) | קיים, או אפשר לשחזר את הנכס |
| עומק התלות | בעיית תאימות ממשק במצב משתמש בלבד | תלוי במנהל, ב-16 סיביות או בחומרה ייעודית |
| חלופות | אין מוצר ארוז או גרסה חדשה | מוצר היעד והטכנולוגיה ברורים |
| השפעה כשנכשל | העסק יכול לרוץ בנוהל גיבוי | העסק הליבתי נפגע ישירות |
| כושר אימות | אפשר לאשר התנהגות בכל עדכון תכונות | אין משאב אימות, ונוטה לקפיאה |
אם מחליטים על הארכת חיים, הכניסו את שלוש הנקודות הבאות לתפעול כסט.
- רשמו. איזה EXE, איזה shim/שכבה, ולמה. השאירו את ערך מפתח Layers ואת GUID ה-.sdb בפנקס. «אף אחד לא יודע למה זה עובד» הוא החוב הגדול ביותר שמשאירים לאדם הבא. זו אותה תפיסת שימור שמכוסה ב«When You Inherit a System With No Source Code and No Documentation».
- אמתו. כללו התחלה ופעולות עיקריות של אפליקציות המוחזקות בחיים על ידי shims בפריטי האימות לעדכון תכונות של Windows. קשרו זאת גם לתוכנית החלפת מערכת ההפעלה (Practical Options After Windows 10 End of Support).
- קבעו מועד יעד. החליטו את סוף הארכת החיים — «עד רענון מערכת הליבה הבא», «עד מרץ 2028» — והריצו שיקולי הגירה במקביל.
flowchart TB
accTitle: סט התפעול התלת-נקודתי אחרי החלטה על הארכת חיים
accDescr: רשמו בפנקס איזה shim גורם לזה לרוץ אמתו התנהגות של אפליקציות המוחזקות בחיים על ידי shims בכל עדכון תכונות קבעו מועד יעד לסוף הארכת החיים והריצו שיקולי הגירה במקביל
decide["החליטו על הארכת חיים"] --> rec["רשמו: איזה shim גורם לזה לרוץ בפנקס"]
rec --> verify["אמתו: אשרו התנהגות בכל עדכון תכונות"]
verify --> deadline["מועד יעד: החליטו את סוף הארכת החיים"]
deadline --> mig["הריצו שיקולי הגירה במקביל"]
איור 18: הארכת חיים מתופעלת כסט תלת-נקודתי של רישום, אימות ומועד יעד, כולל שיקולי הגירה במקביל.
בצד ההגירה האפשרויות הסטנדרטיות משתנות עם טכנולוגיית האפליקציה. ל-VB6 הבחירה המשולשת של שכתוב מלא, המרה אוטומטית והגירה מדורגת שמסודרת ב«How Long Will VB6 Apps Keep Running?»; לתלות ב-ActiveX/OCX טבלת ההחלטה לשמר / לעטוף / להחליף ב«איך מתייחסים היום ל-ActiveX / OCX». הדרך הבריאה למקם shim היא כקניית זמן כדי שתקופת השיקול וההכנה של פרויקט ההגירה ההוא תוכל לרוץ בבטחה.
flowchart TB
accTitle: אפשרויות בצד ההגירה ואיפה יושב shim
accDescr: אפשרויות ההגירה הסטנדרטיות משתנות עם טכנולוגיית האפליקציה; ל-VB6 הבחירה המשולשת שכתוב המרה אוטומטית או הגירה מדורגת ולתלות ActiveX טבלת לשמר לעטוף או להחליף ו-shim ממוקם כקניית זמן לשיקולי פרויקט ההגירה ולהכנתו
tech{"מה טכנולוגיית האפליקציה?"} -->|VB6| vb["שכתוב המרה אוטומטית או הגירה מדורגת"]
tech -->|תלות ActiveX| ax["לשמר לעטוף או להחליף"]
shim["הארכת חיים דרך shim"] -.->|קונה זמן לשיקול ולהכנה| tech
איור 19: אפשרויות ההגירה הסטנדרטיות נקבעות לפי טכנולוגיית האפליקציה, ו-shim ממוקם כקניית זמן לאותו שיקול.
10. סיכום
- הזהות האמיתית של מצב התאימות היא shims. הגדרות מלשונית התאימות נכתבות למפתח AppCompatFlags\Layers ומוזרקות לתהליך בהתחלה כוו API דרך כתיבה מחדש של ה-IAT.
- Shims הם אוסף «שקרים שמחזירים את התשובה שהאפליקציה הישנה מצפה לה». מסופקים shims מוכנים לזיוף גרסה, מיפוי מחדש של נתיבים, זיוף רישום, זיוף בדיקות מנהל וכדומה.
- Windows עצמו משתמש במספר גדול של shims כברירת מחדל, ו-PCA יכול להחיל אותם אוטומטית. הסתמכות על מצב תאימות עצמה היא בחירה סבירה שרוכבת על מנגנון רשמי של מערכת ההפעלה.
- יש גבול עקרוני של מצב משתמש בלבד בלי עקיפת אבטחה, ומנהלי ליבה, אפליקציות 16 סיביות וגישה ישירה לחומרה אי אפשר להציל.
- פריסה ארגונית היא בניית .sdb מותאם ב-Compatibility Administrator (Windows ADK) והפצתו עם sdbinst. בחירת מהדורת 32/64 סיביות, בדיקה בחשבון המשתמש בפועל וניהול עדכונים לפי GUID הן הנקודות המעשיות.
- אפליקציות ש«דורשות מנהל אבל אינן צריכות אותו באמת» אפשר להוריד להרשאות רגילות עם
__COMPAT_LAYER=RunAsInvoker. זו טכניקה הגנתית שמשתיקה את בקשת ההעלאה במקום למסור הרשאות. - ריצה תחת shim היא הארכת חיים, לא פתרון. רישום מה גורם לזה לרוץ, אימות בכל עדכון תכונות, וקביעת מועד יעד כדי שההגירה תרוץ במקביל — הסט התלת-נקודתי הזה כלול בהחלטה «להסתמך על מצב תאימות».
בפעם הבאה שאפליקציה ישנה מתחילה לעבוד אחרי תיבת מצב תאימות, שאלו שוב. «בזכות איזה שקר האפליקציה הזו רצה? כמה זמן השקר הזה ימשיך לעבוד?» אם אפשר לענות, הארכת חיים היא אסטרטגיה מכובדת.
מאמרים קשורים
- Registry 32-bit/64-bit Redirection and Virtualization Pitfalls — Wow6432Node and the “The Value I Wrote Isn’t There” Problem
- How Long Will VB6 Apps Keep Running? — Runtime Support Status and a Practical Path to .NET Migration
- איך מתייחסים היום ל-ActiveX / OCX — טבלת החלטה: לשמר, לעטוף או להחליף
- Practical Options After Windows 10 End of Support — A Decision Table for ESU, LTSC, and Replacement
- When You Inherit a System With No Source Code and No Documentation — A Practical Playbook for Keeping It Running
- אינטגרציית מעטפת Windows היום ── תפריטי הקשר, שיוכי קבצים ומה שהשתנה ב-Windows 11
תחומי ייעוץ קשורים
KomuraSoft LLC מטפלת בחקירת איך מתנהגות אפליקציות עסקיות ישנות בלי קוד מקור ובתכנון הארכת חייהן (בחירת shims ומצב תאימות, בניית .sdb מותאם ופריסתו), באימות תאימות של אפליקציות קיימות להגירת Windows 11, ובתכנון שכתוב או הגירה שרצים במקביל להארכת חיים. ייעוץ משלב «התחיל לעבוד במצב תאימות, אבל מותר להשאיר כך?» בסדר.
קישורי עיון
-
Microsoft Learn, Application Compatibility Database. שתשתית התאימות מנהלת בעיות ותרופות במסד בפורמט .sdb, התאמה לפי תכונות קובץ הפעלה, Apphelp (הצגת הודעה) ו-Appfix (וו API דרך shim), ושכבת תאימות (מצב) שמצררת כמה shims ודגלים. ↩ ↩2 ↩3
-
Microsoft Learn, DXGI overview. שהגדרות תאימות אפליקציות מאוחסנות במפתח הרישום HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers (תוך שימוש בהגדרות תאימות DXGI כדוגמה). ↩ ↩2
-
Microsoft Learn, Understanding and Using Compatibility Fixes. שתיקון תאימות (shim) מפנה קריאות API בכתיבה מחדש של ה-IAT (טבלת כתובות ייבוא), שקישור דינמי מטופל בווי על GetProcAddress, ש-shim כפוף לאותן מגבלות אבטחה כמו האפליקציה ואינו יכול לעקוף מנגנוני אבטחה של מערכת ההפעלה, שהוא מצב משתמש בלבד ואינו יכול לתקן בעיות מנהל, שתיקון אפשרי עם shim אפשרי גם עם תיקון קוד, תרחישי שימוש כמו אפליקציות שתמיכת הספק שלהן הסתיימה, ושתיקוני תאימות שמיקרוסופט מספקת נשלחים כחלק מ-Windows ומתעדכנים דרך Windows Update. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Compatibility Fixes for Windows 10, Windows 8, Windows 7, and Windows Vista. רשימה ותיאור של תיקוני תאימות ידועים כולל CorrectFilePaths, VirtualRegistry, ForceAdminAccess, RunAsAdmin/RunAsHighest/RunAsInvoker, WRPMitigation, EmulateGetDiskFreeSpace, GlobalMemoryStatusLie, LoadLibraryRedirect ומשפחת VersionLie; בחירת מהדורת 32/64 סיביות של Compatibility Administrator; ושבדיקה במצב מוגבה פירושה שווירטואליזציה והפניה אינן מתנהגות כמצופה, ולכן יש לאמת בחשבון המשתמש בפועל. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Program Compatibility Assistant scenarios for Windows 8. ש-PCA צופה בביצוע אפליקציה, מזהה סימנים לבעיית תאימות ידועה, ומציע להחיל תיקון מומלץ או מחיל אותו אוטומטית (PINDLL, DISABLEUSERCALLBACKEXCEPTION, VIRTUALIZEDELETE, WRPMITIGATION וכדומה), והחלת תיקון מלשונית התאימות ומ-Program Compatibility Troubleshooter. ↩ ↩2
-
Microsoft Learn, GetVersionExW function. שמ-Windows 8.1 ואילך הערך ש-GetVersionEx מחזיר תלוי במנשר, שאפליקציה שאינה מנושרת ל-Windows 8.1/10 מקבלת את ערך גרסת Windows 8 (6.2), ושכאשר מצב תאימות מופעל מדווחת גרסת מערכת ההפעלה שנבחרה. ↩ ↩2 ↩3
-
Microsoft Learn, Targeting your application for Windows. איך להכריז GUIDs של מערכות נתמכות עם רכיב supportedOS במדור compatibility של מנשר האפליקציה, ההתנהגות כשאין הכרזה, ואפליקציית x86 32 סיביות אינטראקטיבית שאינה כוללת trustInfo כפופה לווירטואליזציית קבצי UAC (הפניית כתיבה אל VirtualStore). ↩ ↩2
-
Microsoft Learn, Running 32-bit Applications. ש-WOW64 היא שכבת אמולציה שמריצה אפליקציות 32 סיביות על Windows של 64 סיביות ומבודדת התנגשויות קבצים ורישום, וש-Windows של 64 סיביות אינו תומך בהרצת אפליקציות 16 סיביות, עם כשל התחלה ב-ERROR_BAD_EXE_FORMAT בגלל מספר הסיביות התקפות בידית. ↩ ↩2
-
Microsoft Learn, Using the RunAsInvoker Fix. שתיקון התאימות RunAsInvoker מתחיל את האפליקציה עם האסימון שעבר בירושה מתהליך האב, שהוא דורס גם זיהוי מתקין וגם עיבוד מנשר, שהוא מוחל כדגל טוען בלי ליירט ממשקים, ושכאשר אפשר לתקן את הקוד התיקון הנכון הוא להכריז asInvoker במנשר. ↩ ↩2 ↩3
-
Microsoft Learn, Registry Virtualization. שווירטואליזציית רישום היא טכנולוגיית תאימות שמפנה בשקיפות כתיבות גלובליות אל HKLM\Software אל VirtualStore לכל משתמש, שרק תהליכים אינטראקטיביים 32 סיביות בטווח והיא מבוטלת לתהליכים שמציינים requestedExecutionLevel במנשר ולתהליכי 64 סיביות, ושהיא ממוקמת כטכנולוגיה זמנית המיועדת להסרה מ-Windows עתידי. ↩ ↩2
-
Microsoft Learn, High DPI Desktop Application Development on Windows. שאפליקציה שאינה מודעת ל-DPI מטופלת כמציירת ב-96 DPI קבוע ועל צג עם DPI גבוה Windows מוחחת את מפת הסיביות כך שהיא נראית מטושטשת, וההבדלים בין מצבי מודעות DPI (Unaware/System/Per-Monitor). ↩ ↩2
-
Microsoft Learn, Download and install the Windows ADK. ש-Windows ADK כולל Compatibility Administrator ו-Standard User Analyzer, ואיך לחשוב על בחירת גרסת ADK ואיך להוריד ולהתקין אותה. ↩
-
Microsoft Learn, Compatibility Administrator User’s Guide. ש-Compatibility Administrator מספק החלת תיקוני תאימות, מצבי תאימות והודעות AppHelp ויצירת מסד מותאם, ושמהדורות 32 ו-64 סיביות מותקנות שתיהן וחייבים להשתמש במהדורת 32 סיביות לאפליקציות 32 סיביות ובמהדורת 64 סיביות לאפליקציות 64 סיביות. ↩
-
Microsoft Learn, Creating a Custom Compatibility Fix in Compatibility Administrator. שתיקון תאימות (שנקרא בעבר shim) הוא פיסת קוד קטנה שמיירטת קריאת API; הליך יצירת Application Fix במסד מותאם (ציון שם אפליקציה, ספק ו-EXE יעד, בחירת מצב תאימות, בחירת shims נוספים, הגדרת תנאי התאמה); ושצריך להשאיר תנאים שמזהים נכון את האפליקציה תוך צמצום מידע ההתאמה. ↩ ↩2
-
Microsoft Learn, Compatibility Fix Database Management Strategies and Deployment. שמסד מנוהל מרכזית מומלץ כאסטרטגיית ניהול למסד תאימות מותאם, שתיקון תאימות צריך לכלול בדיקת גרסה (תנאי התאמה) כדי שלא יוחל על גרסה חדשה, התקנה מקומית עם Sdbinst.exe (אפשרויות -q, -u, -g), שהתקנת גרסה חדשה עם אותו GUID מסד מסירה אוטומטית את הישנה, ושיטות הפצה דרך MSI או סקריפט. ↩ ↩2 ↩3
מאמרים קשורים
מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.
Win32 Thread Pool API — מקביליות בלי ליצור תהליכונים, דרך CreateThreadpoolWork
מפזרים קריאות CreateThread בכל הקוד הנייטיב? המאמר מסביר את ה-API של מאגר התהליכונים של Win32 שעוצב מחדש ב-Vista — ארבעת האובייקטים work,...
Named Pipes בפועל — ה-IPC הסטנדרטי של Windows, מתכנון ועד אבטחה
מדריך מעשי ל-Named Pipes, התקשורת הסטנדרטית בין תהליכים ב-Windows. המאמר מסדר ממקורות ראשוניים את הבחירה בין מצב בתים למצב הודעות, תכנון ...
יישומים שנשברים בחזרה משינה — איך אירועי צריכת החשמל של Windows עובדים ואיך לבנות יישומים עסקיים ששורדים אותם
פתחתם את המחשב הנייד והחיבורים של היישום העסקי היו מתים — הסיבה היא תכנון שלא חשב על שינה. המאמר מכסה את זרימת ההודעות WM_POWERBROADCAST,...
DllMain ונעילת הטוען — הסיבה האמיתית שאומרים לכם "לא לעשות כלום באתחול DLL"
למה אסור לקרוא ל-LoadLibrary או להסתנכרן עם תהליכונים אחרים מתוך DllMain. המאמר מסביר ממקורות ראשוניים איך נעילת הטוען מסדרת כל הודעת DLL...
מה "לא מגיב" באמת — איך Windows מחליט שיישום נתקע, ואיך לתכנן יישומים שלא
"לא מגיב" של Windows הוא מנגנון שבו מערכת ההפעלה קובעת שחלון לא שלף הודעה במשך 5 שניות ומחליפה אותו בחלון רפאים. המאמר מכסה את פנים השיפו...
נושאים קשורים
העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.
נושאים טכניים ב-Windows
שער לנושאי פיתוח Windows, חקירת תקלות וניצול נכסים קיימים.
שירותים הקשורים לנושא הזה
המאמר קשור ישירות לשירותים הבאים.
פיתוח יישומי Windows
יישומים עסקיים, חיבור התקנים וכלי תקשורת, מהגדרת הדרישות ועד הפיתוח.
שאלות נפוצות
שאלות נפוצות בפניות בנושא המאמר.
- אם האפליקציה התחילה לעבוד אחרי שסימנתי מצב תאימות, מותר להמשיך כך?
- כדי לשמור על העסק רץ בטווח הקצר, כן. מצב תאימות הוא וו API במצב משתמש שנקרא shim, מנגנון רשמי שמספקת מערכת ההפעלה. אבל shim נשאר תחליף זמני להרצת אפליקציה בלי לתקן אותה, ועדכון OS אחר יכול לשנות את ההנחות ולשבור אותה שוב. רשמו בפנקס שהיא רצה במצב תאימות, וטפלו ברישום כחלק מההחלטה לשכתב את האפליקציה או להאריך את חייה בכוונה.
- מה תיבת הסימון של מצב התאימות באמת עושה?
- כששומרים הגדרות בלשונית התאימות בתיבת המאפיינים, Windows כותב את נתיב ה-EXE היעד וערך כמו "WINXPSP3" או "HIGHDPIAWARE" תחת המפתח HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers. בפעם הבאה שה-EXE הזה מתחיל, הטוען של Windows קורא את הערך ומחיל על התהליך את שכבת התאימות המתאימה (צרור shims). מצב תאימות של Windows XP, למשל, מזייף את גרסת מערכת ההפעלה בהחזרת ערך ישן מממשקי שאילתת גרסה. מערכת ההפעלה עצמה אינה משתנה; רק לאותו תהליך מוצג Windows ישן מזויף.
- אפשר להריץ אפליקציות מתקופת 16 סיביות במצב תאימות על Windows של 64 סיביות?
- לא. Windows של 64 סיביות מריץ אפליקציות 32 סיביות דרך WOW64, אבל אינו תומך בהרצת אפליקציות 16 סיביות, וניסיון התחלה נכשל עם ERROR_BAD_EXE_FORMAT. זה גבול ארכיטקטוני ש-shim אינו יכול לעקוף. חבילות ישנות שקדם-ההתקנה שלהן הוא 16 סיביות נכשלות מאותה סיבה. אם באמת צריך אותן, צריך להסתכל מחוץ למצב תאימות — למשל מכונה וירטואלית שכוללת Windows של 32 סיביות.
- אפשר להריץ אפליקציה ש«לא תתחיל אלא אם מריצים כמנהל» תחת חשבון משתמש רגיל?
- RunAsInvoker שווה ניסיון. אם מריצים set __COMPAT_LAYER=RunAsInvoker בשורת הפקודה ואז מתחילים את האפליקציה, בקשות העלאה ממנשר requireAdministrator או מזיהוי מתקין מדוכאות, והאפליקציה מתחילה באותן הרשאות (משתמש רגיל) כמו הקורא. לאפליקציה שרק מבקשת הרשאות מנהל ואינה משתמשת בהן באמת, זה לבדו יכול להוציא העלאה מהתפעול היומיומי. ההרשאות אינן גדלות, ולכן עבודה שבאמת צריכה הרשאות מנהל תיכשל בתוך האפליקציה. לאמצו רק אחרי שאימתתם את ההתנהגות.
- איפה משיגים את Compatibility Administrator?
- כלול ב-Windows ADK (Windows Assessment and Deployment Kit). הורידו את ה-ADK מאתר מיקרוסופט, ובהתקנה בחרו את תכונות Application Compatibility Tools. מהדורות 32 סיביות ו-64 סיביות מותקנות שתיהן; חייבים להשתמש במהדורת 32 סיביות לאפליקציות 32 סיביות ובמהדורת 64 סיביות לאפליקציות 64 סיביות. החילו מסד תאימות מותאם (.sdb) שיצרתם בהרצת הפקודה sdbinst על כל מחשב.