Cách Windows tương thích ứng dụng hoạt động — chế độ tương thích, shim và Compatibility Administrator
· Go Komura · Windows, Chế độ tương thích, Shim, Tương thích ứng dụng, Compatibility Administrator, Tái sử dụng tài sản hiện có, Phát triển Windows, Hệ thống hiện có
«Một ứng dụng nghiệp vụ mười năm tuổi, mã nguồn đã mất, không khởi động trên PC Windows 11 mới. Tôi tích “Windows XP” trên tab Tương thích của hộp thoại thuộc tính và nó cứ chạy. — Thực sự điều đó đang làm gì? Có ổn không nếu tiếp tục dựa vào nó?» Đó là tư vấn chúng tôi thường nghe.
Khi một hộp kiểm duy nhất làm thứ gì đó chạy được, cảm giác bất an là tự nhiên. Bản sắc thật của chế độ tương thích, trông như phép thuật, là tập hợp những mảnh mã nhỏ gọi là shim nằm giữa ứng dụng và Windows API rồi trả về một «lời nói dối». Bản thân Windows dùng biện pháp tạm này ở quy mô lớn để giữ ứng dụng nhiều thế hệ vẫn chạy, và mở một phần cơ chế cho người dùng cùng quản trị viên.
Dùng mà không hiểu cơ chế, kéo dài tuổi thọ trở thành trạng thái không ổn định «không được đụng vì không biết vì sao nó chạy». Hiểu cơ chế thì bạn có thể quyết định, có lý do, dựa được đến đâu cho an toàn, điều gì sẽ làm nó hỏng, và khi nào nên viết lại.
flowchart TB
accTitle: Hiểu cơ chế làm thay đổi chất lượng kéo dài tuổi thọ
accDescr: Dùng chế độ tương thích mà không hiểu cơ chế dẫn tới kéo dài tuổi thọ không ổn định không dám đụng; hiểu cơ chế cho phép quyết định có lý do dựa được đến đâu, điều gì làm hỏng, và khi nào nên viết lại
unknown["Dùng mà không hiểu cơ chế"] --> fear["Kéo dài tuổi thọ không ổn định không dám đụng"]
known["Dùng sau khi hiểu cơ chế"] --> judge["Quyết định có lý do"]
judge -.-> j1["Dựa được đến đâu"]
judge -.-> j2["Điều gì sẽ làm hỏng"]
judge -.-> j3["Khi nào nên viết lại"]
Hình 1: Cùng một việc kéo dài tuổi thọ, chất lượng khác nhau giữa lo lắng vì không biết cơ chế và quyết định dựa trên hiểu biết.
Hướng tới nhân viên IT doanh nghiệp vừa và nhỏ cùng các nhà phát triển ứng dụng Windows chăm sóc ứng dụng nghiệp vụ cũ, bài viết này sắp xếp, từ nguồn gốc Microsoft Learn, cơ chế shim — bản sắc thật của chế độ tương thích — những gì các shim tiêu biểu làm được, cách áp chúng theo tổ chức bằng Compatibility Administrator, giới hạn shim không cứu nổi, và cách quyết định giữa kéo dài tuổi thọ và di chuyển.
1. Kết luận trước
- Bản sắc thật của chế độ tương thích là shim (lớp tương thích). Cài đặt từ tab Tương thích được ghi vào
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers, và một bó shim được áp lên tiến trình lúc khởi động.12 - Shim là hook API user-mode viết lại bảng địa chỉ nhập (IAT). Nó chặn đường ứng dụng gọi Windows API và trả về cùng câu trả lời mà Windows cũ từng đưa. Nó không đổi bản thân OS.3
- Những gì shim làm được cùng phạm vi với sửa mã trong ứng dụng. Nó không vượt cơ chế bảo mật, và không sửa được vấn đề kernel-mode (trình điều khiển thiết bị).3
- Microsoft xuất xưởng rất nhiều shim sẵn — nói dối phiên bản, ánh xạ lại đường dẫn tệp, giả mạo registry, giả mạo kiểm tra quản trị, và hơn thế. Bạn có thể áp chúng lên từng EXE từ Compatibility Administrator.4
- Bản thân Windows dùng shim theo mặc định. Cơ sở dữ liệu tương thích chuẩn OS (.sdb) được đối chiếu mỗi lần khởi chạy, và PCA (Program Compatibility Assistant) cũng có thể phát hiện sự cố rồi tự áp cài đặt tương thích.15
- «Trả lời như thể đây là Windows cũ hơn» giờ là mặc định. Từ Windows 8.1 trở đi,
GetVersionExkhông trả về phiên bản OS mà ứng dụng chưa khai báo trong manifest. Chế độ tương thích là phần mở rộng của cơ chế đó.67 - Shim không có tác dụng với ứng dụng 16-bit, phụ thuộc trình điều khiển kernel, hay truy cập phần cứng trực tiếp. Đặc biệt, ứng dụng 16-bit hoàn toàn không chạy được trên Windows 64-bit.8
- Với ứng dụng «yêu cầu quản trị nhưng thực sự không cần», RunAsInvoker là nước đi chuẩn.
__COMPAT_LAYER=RunAsInvokerchặn yêu cầu nâng quyền và để ứng dụng chạy dưới quyền chuẩn.9 - Chạy dưới shim nghĩa là bạn có thể kéo dài tuổi thọ lúc này, nhưng đường thật vẫn là «làm cho nó chạy không cần shim». Nếu quyết định kéo dài, ghi lại shim nào làm nó chạy và quản lý đó như tư liệu quyết định viết lại.
2. Bức tranh lớn về tương thích ứng dụng — các lớp tương thích ngược Windows đã có
Trước khi nói về shim, đây là danh sách cơ chế Windows đã có cho ứng dụng cũ. Dù người ta nói «nó bắt đầu chạy ở chế độ tương thích», thứ thực sự cứu ứng dụng là một trong các lớp này, hoặc tổ hợp vài lớp.
| Lớp | Việc nó làm | Đối tượng điển hình |
|---|---|---|
| Shim (chế độ tương thích) | Chặn lời gọi API và giả mạo cùng phản hồi mà Windows cũ từng đưa | Ứng dụng viết cho OS cũ nói chung |
| Ảo hóa UAC (tệp / registry) | Chuyển hướng ghi vào HKLM\Software hoặc Program Files thiếu quyền sang VirtualStore theo người dùng |
Ứng dụng 32-bit viết với giả định quyền quản trị |
| WOW64 | Chạy ứng dụng 32-bit nguyên trạng trên Windows 64-bit (cung cấp góc nhìn 32-bit của registry và hệ thống tệp) | Ứng dụng 32-bit nói chung |
| Ảo hóa DPI | Cho ứng dụng không nhận DPI vẽ ở 96 DPI rồi hiển thị bằng cách kéo giãn bitmap | Ứng dụng cũ trên màn hình DPI cao |
Ảo hóa UAC là biện pháp chuyển tiếp áp cho tiến trình tương tác 32-bit không có manifest, và chính Microsoft nói đó là «công nghệ tạm thời chúng tôi dự định gỡ khỏi một phiên bản Windows trong tương lai».10 Thiệt hại thực từ chuyển hướng Wow6432Node và VirtualStore, cùng cách xử lý, được trình bày chi tiết trong «Registry 32-bit/64-bit Redirection and Virtualization Pitfalls»; bài này giữ shim ở trung tâm và chỉ nhắc các lớp khác khi cần.
flowchart TB
accTitle: Vị trí của ảo hóa UAC
accDescr: Ảo hóa UAC là biện pháp chuyển tiếp cho tiến trình tương tác 32-bit không có manifest; nó chuyển hướng ghi sang VirtualStore theo người dùng, nhưng chính Microsoft nói đó là công nghệ tạm thời dự định gỡ khỏi Windows tương lai
proc["Tiến trình tương tác 32-bit không có manifest"] --> uacv["Ảo hóa UAC được áp"]
uacv --> vs["Chuyển hướng sang VirtualStore theo người dùng"]
uacv -.-> tmp["Công nghệ tạm thời dự định gỡ sau"]
Hình 2: Ảo hóa UAC là biện pháp chuyển tiếp cho tiến trình 32-bit không có manifest, và bạn không thể dựa vào nó vĩnh viễn.
Ghi chú bên về ảo hóa DPI: ứng dụng chưa khai báo nhận biết DPI được coi như vẽ ở 96 DPI (100%), và Windows kéo giãn bitmap để hiển thị. Đó là lý do ứng dụng cũ trông «nhòe» trên màn hình DPI cao, và «Ghi đè hành vi chia tỷ lệ DPI cao» trên tab Tương thích là công tắc đổi hành vi ảo hóa này.11
flowchart TB
accTitle: Cách ảo hóa DPI hoạt động
accDescr: Ứng dụng chưa khai báo nhận biết DPI được coi như vẽ ở 96 DPI; Windows kéo giãn bitmap nên trông nhòe, và ghi đè cài đặt DPI cao trên tab Tương thích chuyển hành vi ảo hóa này
app["Ứng dụng không khai báo nhận biết DPI"] --> treat["Được coi như vẽ ở 96 DPI"]
treat --> stretch["Bitmap được kéo giãn để hiển thị"]
stretch --> blur["Trông nhòe trên màn hình DPI cao"]
tab["Ghi đè hành vi chia tỷ lệ DPI cao"] -.->|Chuyển hành vi ảo hóa| treat
Hình 3: Ứng dụng không nhận DPI được coi là 96 DPI và bị kéo giãn; ghi đè trên tab Tương thích là công tắc của ảo hóa này.
3. Shim thực sự là gì — chặn giữa các API bằng cách viết lại IAT
3.1. «Người phiên dịch» đứng giữa ứng dụng và OS
Tệp thực thi Windows (định dạng PE) gọi API trong DLL ngoài qua bảng địa chỉ nhập (IAT). Khi ứng dụng gọi GetVersionEx, nó chỉ nhảy tới địa chỉ ghi trong IAT. Cơ chế shim khai thác điều đó. Lúc nạp nó viết lại mục IAT của API đích thành địa chỉ mã shim và chèn mình giữa ứng dụng và Windows. API lấy động qua GetProcAddress được xử lý bằng cách móc chính GetProcAddress.3
Sau khi chặn, shim có thể trả số phiên bản cũ cho «phiên bản OS hiện tại là gì?», hoặc ánh xạ lại truy cập tệp tới vị trí không ghi được sang chỗ khác, rồi gọi API thật nếu cần. Từ phía ứng dụng như thể «đang chạy trên Windows cũ»; từ phía OS như thể «một ứng dụng ngoan đang chạy» — shim là người phiên dịch giữa hai bên.
flowchart TB
accTitle: Đường shim chặn lời gọi API
accDescr: Lời gọi API của ứng dụng đi qua IAT; viết lại mục IAT thành shim lúc nạp giúp shim chặn, giả mạo cùng phản hồi mà Windows cũ từng đưa, rồi gọi API thật nếu cần
app["Ứng dụng"] -->|Lời gọi API| iat["Mục IAT"]
iat -->|Viết lại thành shim lúc nạp| shim["Shim (người phiên dịch)"]
shim -->|Nếu cần| api["Windows API thật"]
shim -.-> lie["Giả mạo cùng phản hồi mà Windows cũ từng đưa"]
gpa["Gọi qua GetProcAddress"] -.->|Xử lý bằng hook| shim
Hình 4: Shim chặn giữa ứng dụng và Windows API. Thứ bị viết lại là IAT phía ứng dụng; bản thân OS không đổi.
Ba tính chất quan trọng theo từ thiết kế này.3
- Shim chạy như mã phía ứng dụng. Nó không phải một phần OS, nên chịu cùng ràng buộc bảo mật như ứng dụng. Shim không vượt cơ chế bảo mật OS, và bạn không cần nới cài đặt bảo mật để dùng shim.
- Điều shim sửa được, sửa mã phía ứng dụng cũng sửa được. Shim là vật thay cho trường hợp «không có nguồn / không sửa được»; nó không mạnh hơn sửa mã.
- Chỉ user mode. Vấn đề tương thích của trình điều khiển thiết bị chạy ở kernel mode không thể sửa bằng shim.
3.2. Cơ sở dữ liệu shim (.sdb) và đối chiếu
Bảng tương ứng «shim nào áp cho EXE nào» là cơ sở dữ liệu shim, tệp nhị phân phần mở rộng .sdb. Tệp thực thi ứng dụng đích được đăng ký trong cơ sở theo thuộc tính như tên tệp, kích thước, checksum và phiên bản (thuộc tính đối chiếu), rồi được đối chiếu lúc tiến trình khởi động. Biện pháp gồm Appfix (một shim), tiêm hook API, và Apphelp, hiện thông báo «ứng dụng này có vấn đề tương thích». Một bó vài shim và cờ là lớp tương thích (chế độ tương thích).1
Dễ bỏ sót: đối chiếu này không chỉ chạy trên ứng dụng đã đặt chế độ tương thích, mà trên mọi lần khởi chạy tiến trình. Windows xuất xưởng cơ sở chuẩn OS chứa bản sửa cho hàng nghìn ứng dụng đã biết (tệp nằm dưới %WINDIR%\AppPatch), và trên PC bạn hôm nay gần như chắc có ứng dụng cũ đang khởi động với shim gắn sẵn mà không ai để ý. Các bản sửa tương thích do Microsoft cung cấp được xuất như một phần Windows và cập nhật qua Windows Update.3
flowchart TB
accTitle: Đối chiếu cơ sở dữ liệu shim lúc tiến trình khởi động
accDescr: Mỗi lần khởi chạy tiến trình được đối chiếu với cơ sở dữ liệu shim; nếu một đăng ký khớp thuộc tính đối chiếu, Appfix tiêm shim hoặc Apphelp hiện thông báo, nếu không tiến trình khởi động nguyên trạng
start["Tiến trình khởi động"] --> db["Đối chiếu với .sdb"]
db -.-> attr["Tên tệp, kích thước, v.v."]
db --> hit{"Có đăng ký?"}
hit -->|Có| appfix["Appfix: tiêm shim"]
hit -->|Có| apphelp["Apphelp: một thông báo"]
hit -->|Không| plain["Khởi động nguyên trạng"]
layer["Lớp tương thích"] -.->|bó shim và cờ| appfix
Hình 5: Đối chiếu chạy trên mọi lần khởi chạy tiến trình, không chỉ trên ứng dụng đã đặt chế độ tương thích.
3.3. PCA — cơ chế tự áp shim
Một đường khác để shim được áp mà quản trị viên không chủ ý là PCA (Program Compatibility Assistant). PCA theo dõi thực thi ứng dụng và, khi phát hiện dấu hiệu sự cố tương thích đã biết, đề xuất áp bản sửa cho người dùng hoặc, trong một số trường hợp, tự áp cài đặt tương thích. Ví dụ, ứng dụng sập vì gọi mã trong DLL đã giải phóng được gán PINDLL, và ứng dụng ghi tệp Windows được bảo vệ thất bại được gán WRPMITIGATION.5
flowchart TB
accTitle: Cách PCA tự áp cài đặt tương thích
accDescr: PCA theo dõi thực thi ứng dụng và, khi phát hiện dấu hiệu sự cố tương thích đã biết, đề xuất áp bản sửa cho người dùng hoặc, trong một số trường hợp, tự áp cài đặt tương thích
run["Thực thi ứng dụng"] --> pca["PCA theo dõi"]
pca --> sign{"Dấu hiệu sự cố đã biết?"}
sign -->|Có| resp{"Trường hợp nào?"}
resp -->|Xử lý bằng đề xuất| suggest["Đề xuất áp bản sửa"]
resp -->|Một số trường hợp| auto["Tự áp cài đặt tương thích"]
sign -->|Không| none["Chạy nguyên trạng"]
auto -.-> ex["Ví dụ: PINDLL hoặc WRPMITIGATION"]
Hình 6: PCA theo dõi thực thi ứng dụng và, khi phát hiện dấu hiệu sự cố đã biết, đề xuất bản sửa hoặc tự áp một bản.
Bản sắc của «tôi chưa từng đặt gì, nhưng lúc nào đó hộp kiểm chế độ tương thích đã bật» trong nhiều trường hợp chính là điều này. Không phải lỗi cũng không phải nhầm nút; Windows hành xử như thiết kế.
4. Những gì các shim tiêu biểu làm được
Từ các shim sẵn Microsoft công bố, đây là lựa chọn thực sự thường gặp khi kéo dài tuổi thọ ứng dụng nghiệp vụ.4
| Shim | Việc nó làm được (tóm tắt) |
|---|---|
| WinXPSP3VersionLie và các shim họ VersionLie khác | Trả về phiên bản cũ được chỉ định cho truy vấn phiên bản OS (giả mạo phiên bản) |
| CorrectFilePaths | Ánh xạ lại truy cập đường dẫn tệp không ghi được hoặc không tồn tại sang vị trí khác |
| VirtualRegistry | Chuyển hướng hoặc giả mạo đọc ghi registry (kể cả giả mạo phiên bản và giả khóa không tồn tại) |
| ForceAdminAccess | Tạm trả True cho kiểm tra «bạn có phải thành viên nhóm Administrators?» |
| RunAsAdmin / RunAsHighest / RunAsInvoker | Từ bên ngoài cấp mức thực thi tương đương requireAdministrator / highestAvailable / asInvoker trong manifest |
| WRPMitigation | Giả mạo thành công ghi vào tệp OS và khóa registry được bảo vệ để ứng dụng tiếp tục |
| EmulateGetDiskFreeSpace | Báo dung lượng đĩa trống tối đa 2GB (cho ứng dụng tràn trên đĩa lớn) |
| GlobalMemoryStatusLie | Giả mạo giá trị trạng thái bộ nhớ được báo (cho ứng dụng trượt kiểm tra bộ nhớ lúc khởi động) |
| LoadLibraryRedirect | Nạp DLL hiện tại của Windows thay vì DLL hệ thống cũ ứng dụng mang theo |
Nhìn danh sách, hầu hết shim là «lời nói dối trả về câu trả lời ứng dụng cũ mong đợi». Đĩa tối đa 2GB, OS là XP, bạn là quản trị viên — chúng tái tạo, chỉ trong tiến trình đó, thế giới quan thời ứng dụng ra đời.
Giả mạo phiên bản đã trở thành «hành vi mặc định chính thức»
Giả mạo phiên bản không phải thủ thuật đặc biệt. Từ Windows 8.1, giá trị GetVersionEx trả về phụ thuộc manifest ứng dụng. Ứng dụng không có khai báo <supportedOS> trong mục <compatibility> của manifest luôn được cho tương đương Windows 8 (6.2), dù OS thật là gì. Khi có khai báo, giá trị tới OS cao nhất trong các OS đã khai báo được trả về (ví dụ, nếu bạn khai báo tới GUID Windows 8.1, bạn nhận 6.3 ngay cả trên Windows 11).67
Vậy «phiên bản Windows ứng dụng thấy» được quyết định theo các tầng xếp chồng này.
- Giá trị tới OS khai báo trong manifest được trả về (6.2 nếu không có khai báo)
- Nếu chế độ tương thích (shim họ VersionLie) được áp, phiên bản OS đã chọn được trả về6
flowchart TB
accTitle: Cách phiên bản OS ứng dụng thấy được quyết định
accDescr: Giá trị GetVersionEx trả về được quyết định bởi việc có khai báo supportedOS trong manifest hay không; không khai báo thì trả về tương đương Windows 8 6.2, có khai báo thì giá trị tới OS cao nhất đã khai báo, và nếu shim họ VersionLie được áp thì bị ghi đè bằng phiên bản OS đã chọn
q["Truy vấn GetVersionEx"] --> m{"Có khai báo supportedOS?"}
m -->|Không| v62["Tương đương Windows 8 (6.2) được trả về"]
m -->|Có| decl["Giá trị tới OS cao nhất đã khai báo"]
v62 --> lie{"Shim họ VersionLie được áp?"}
decl --> lie
lie -->|Có| fake["Giá trị OS chọn trong chế độ tương thích"]
lie -->|Không| asis["Giá trị được trả về nguyên trạng"]
Hình 7: Phiên bản Windows ứng dụng thấy được quyết định theo các tầng xếp chồng bởi manifest và bởi shim.
Nếu ứng dụng nội bộ «rẽ nhánh theo phiên bản OS và, khó hiểu, bị đánh là 8 dù đây là Windows 11», trước hết hãy nghi khai báo supportedOS trong manifest. Nói ngược lại, ứng dụng cũ từ chối khởi động vì kiểm tra phiên bản, với xác suất cao, có thể vượt qua bằng shim VersionLie. Nhiều trường hợp nó chỉ nhìn số phiên bản, và hành vi thật vẫn ổn trên OS mới hơn.
flowchart TB
accTitle: Hai triệu chứng do phiên bản và cách xử lý
accDescr: Nếu ứng dụng nội bộ bị đánh là 8 dù đây là Windows 11, nghi khai báo supportedOS trong manifest; ứng dụng cũ từ chối khởi động vì kiểm tra phiên bản, với xác suất cao, có thể vượt qua bằng shim VersionLie
sym1["Bị đánh là 8 dù đây là Windows 11"] --> fix1["Nghi khai báo supportedOS"]
sym2["Từ chối khởi động vì kiểm tra phiên bản"] --> fix2["Thử vượt bằng VersionLie"]
fix2 -.-> why["Hành vi thật thường ổn trên OS mới hơn"]
Hình 8: Khi đánh giá đã cũ, nghi manifest; khi từ chối khởi động, nghi VersionLie.
5. Hộp kiểm chế độ tương thích làm gì
Cài đặt từ Thuộc tính → tab Tương thích được lưu trong khóa registry AppCompatFlags\Layers. Cài đặt tương thích ứng dụng DXGI và tương tự dùng cùng khóa làm nơi chỉ định lớp tương thích.2 Hãy xem thật.
reg query "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
Với EXE bạn đặt «Windows XP (Service Pack 3)», «Chạy chương trình này với quyền quản trị» và «Ghi đè hành vi chia tỷ lệ DPI cao» trên tab Tương thích, bạn sẽ thấy giá trị như sau.
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
C:\LegacyApp\Gyomu.exe REG_SZ ~ WINXPSP3 RUNASADMIN HIGHDPIAWARE
Tương ứng tiêu biểu giữa mục hộp kiểm và giá trị (xác nhận trên Windows 11; tên mục và giá trị có thể đổi theo phiên bản OS).
| Mục tab Tương thích | Giá trị ghi (ví dụ) | Thực chất là gì |
|---|---|---|
| Chế độ tương thích: Windows XP (Service Pack 3) | WINXPSP3 | Lớp tương thích bó giả mạo phiên bản và vài shim khác |
| Chế độ màu giảm (8-bit / 256 màu) | 256COLOR | Nới cho chế độ màu cũ |
| Chạy ở độ phân giải màn hình 640 × 480 | 640X480 | Chạy ở độ phân giải thấp |
| Tắt tối ưu toàn màn hình | DISABLEDXMAXIMIZEDWINDOWEDMODE | Tắt tối ưu vẽ khi toàn màn hình |
| Ghi đè hành vi chia tỷ lệ DPI cao (Ứng dụng) | HIGHDPIAWARE | Dừng ảo hóa DPI (kéo giãn bitmap)11 |
| Chạy chương trình này với quyền quản trị | RUNASADMIN | Yêu cầu nâng quyền lúc khởi động |
Ba điểm cần giữ.
- «Chạy chương trình này với quyền quản trị» được ghi cùng chỗ. Chế độ tương thích và cờ nâng quyền sống chung trong cùng khóa Layers, và đó là nơi sinh ra nhầm lẫn «tôi đặt chế độ tương thích rồi nâng quyền đi theo / biến mất». Nhìn thẳng giá trị tách hai thứ.
- Thứ ghi trong HKCU là «cài đặt của người dùng đó». Nếu bạn đặt từ «Thay đổi cài đặt cho mọi người dùng» trên tab, nó được ghi vào khóa cùng tên phía HKLM và áp cho mọi người dùng. Khi phân phối trong imaging, hãy ý thức mình đang ghi phía nào.
- Hộp kiểm chỉ là cửa vào các lớp sẵn. Tab chỉ cho chọn lớp tiêu biểu; bạn không chọn từng shim rồi ghép. Đó là việc Compatibility Administrator ở chương sau.
flowchart TB
accTitle: Đường từ cài đặt tab Tương thích đến khi có hiệu lực
accDescr: Cài đặt tab Tương thích được lưu thành đường dẫn EXE và giá trị trong khóa AppCompatFlags Layers; lần EXE đó khởi động tiếp theo, bộ nạp đọc giá trị và áp lớp tương thích tương ứng lên tiến trình
tab["Đặt trên tab Tương thích"] --> reg["Lưu đường dẫn EXE và giá trị vào khóa Layers"]
reg --> boot["Lần khởi động EXE tiếp theo"]
boot --> loader["Bộ nạp đọc giá trị"]
loader --> apply["Áp lớp tương thích lên tiến trình"]
reg -.-> hkcu["HKCU chỉ người dùng đó"]
reg -.-> hklm["HKLM áp cho mọi người dùng"]
Hình 9: Hộp kiểm thực chất là ghi vào khóa Layers, và việc áp xảy ra ở lần khởi động tiếp theo.
6. Compatibility Administrator trong thực tế — xây và phân phối .sdb tùy chỉnh
6.1. Cách lấy, và lưu ý
Compatibility Administrator là công cụ nằm trong Windows ADK (Windows Assessment and Deployment Kit).12 Sau khi cài, cả bản 32-bit và 64-bit đều có, và bạn phải dùng bản 32-bit cho ứng dụng 32-bit và bản 64-bit cho ứng dụng 64-bit.13
Còn một lưu ý quan trọng khác. Nếu bạn khởi động Compatibility Administrator ở trạng thái nâng (với quyền quản trị) rồi kiểm tra, ảo hóa UAC và chuyển hướng không hành xử như với người dùng thật, và bạn có thể đánh giá sai rằng «đã sửa». Luôn xác nhận hiệu quả bản sửa bằng cùng tài khoản và quyền như người dùng thực tế.4
flowchart TB
accTitle: Hai lưu ý khi dùng Compatibility Administrator
accDescr: Dùng bản 32-bit cho ứng dụng 32-bit và bản 64-bit cho ứng dụng 64-bit, và xác nhận hiệu quả bản sửa bằng cùng tài khoản và quyền như người dùng thực tế, không ở trạng thái nâng
app32["Ứng dụng 32-bit"] --> tool32["Dùng bản 32-bit"]
app64["Ứng dụng 64-bit"] --> tool64["Dùng bản 64-bit"]
elev["Kiểm tra ở trạng thái nâng"] -.-> wrong["Có thể đánh giá sai bản sửa"]
user["Kiểm tra với quyền người dùng thực"] --> ok["Xác nhận hiệu quả"]
Hình 10: Chọn bản 32-bit hay 64-bit, và xác nhận với cùng quyền như người dùng thực tế, là lưu ý ngay cửa vào.
6.2. Quy trình xây cơ sở dữ liệu tương thích tùy chỉnh
Đại cương như sau.14
- Ở ngăn trái Compatibility Administrator, tạo cơ sở mới dưới «Custom Databases» và chọn «Create New» → «Application Fix»
- Nhập tên ứng dụng và tên nhà cung cấp, rồi chỉ định tệp EXE đích
- Chọn chế độ tương thích (lớp) để áp — thử bó như «tương thích Windows XP» trước là đường ngắn
- Nếu cần, thêm từng bản sửa tương thích (shim) — bạn có thể thu hẹp còn bộ tối thiểu như chỉ VersionLie hoặc chỉ CorrectFilePaths
- Xác nhận điều kiện đối chiếu (kích thước tệp, checksum, phiên bản, v.v.) rồi lưu
Điều kiện đối chiếu là chìa khóa «chỉ áp cái này cho EXE này». Điều kiện cơ bản mặc định thường đủ, nhưng chúng tôi khuyên để lại điều kiện có thể nhận diện phiên bản ứng dụng. Điều đó ngăn tai nạn lời nói dối cũ tiếp tục áp lên phiên bản mới khi nhà cung cấp sau này phát hành bản đã sửa.1415
flowchart TB
accTitle: Quy trình xây cơ sở dữ liệu tương thích tùy chỉnh
accDescr: Tạo Application Fix trong cơ sở mới, chỉ định tên ứng dụng và EXE đích, thử bó chế độ tương thích trước rồi thu hẹp từng shim nếu cần, xác nhận điều kiện đối chiếu và lưu
new["Tạo cơ sở mới"] --> fix["Chọn Application Fix"]
fix --> info["Chỉ định tên ứng dụng và EXE đích"]
info --> layer["Thử bó chế độ tương thích"]
layer --> single["Nếu cần, thu hẹp từng shim"]
single --> match["Xác nhận điều kiện đối chiếu và lưu"]
match -.-> ver["Để lại điều kiện nhận diện phiên bản"]
Hình 11: Với Application Fix, thử bó chế độ tương thích trước, thu hẹp còn bộ tối thiểu, và giới hạn đích bằng điều kiện đối chiếu.
Kiểm tra .sdb bạn tạo trên máy xác nhận trước. Khi chạy đúng ý, bạn triển khai ra tổ chức.
6.3. Phân phối bằng sdbinst
Lệnh áp .sdb tùy chỉnh lên mỗi PC là sdbinst.exe (cần quyền quản trị).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}
Với chiến lược triển khai tổ chức, Microsoft khuyên gộp thành một cơ sở tùy chỉnh toàn công ty (hoặc theo phòng ban) và quản lý tập trung, thay vì gửi .sdb riêng kèm trình cài đặt mỗi ứng dụng. Càng nhiều bản sửa, càng dễ cập nhật và phân phối lại một cơ sở hơn là phân phối nhiều cơ sở một dòng. Cơ sở tùy chỉnh có GUID riêng, và cài phiên bản mới với cùng GUID tự thay phiên bản cũ, nên thao tác cập nhật cũng đơn giản. Đặt bản thân việc phân phối trên đường sẵn có thể chạy với quyền quản trị, ví dụ đóng gói MSI hoặc tập lệnh khởi động.15
flowchart TB
accTitle: Đường từ tạo .sdb tùy chỉnh đến phân phối
accDescr: Tạo cơ sở dữ liệu tương thích tùy chỉnh trong Compatibility Administrator, kiểm tra trên máy xác nhận, áp lên mỗi PC bằng sdbinst, và khi cập nhật cài phiên bản mới với cùng GUID để phiên bản cũ được thay tự động
make["Tạo trong Compatibility Administrator"] --> test["Kiểm tra trên máy xác nhận"]
test --> deploy["Áp lên mỗi PC bằng sdbinst"]
deploy --> update["Cài phiên bản mới với cùng GUID"]
update -.-> replace["Phiên bản cũ được thay tự động"]
deploy -.-> inv["Đăng ký trong Programs and Features"]
Hình 12: .sdb tùy chỉnh được triển khai qua tạo, xác nhận và phân phối sdbinst, còn cập nhật được quản lý theo GUID.
Cơ sở tùy chỉnh đã cài được đăng ký như một mục trong «Programs and Features (Ứng dụng đã cài)», nên bạn cũng có thể xác nhận tồn kho và gỡ từ đó. PC nào có .sdb nào là thông tin thuộc sổ cái quản lý tài sản.
7. Trường hợp không có tác dụng, và giới hạn
Shim không phải viên đạn bạc. Theo thiết kế chúng không có tác dụng trong các trường hợp sau.
- Vấn đề kernel-mode. Shim chạy trong tiến trình user-mode, nên không tương thích trình điều khiển thiết bị không sửa được. Nếu trình điều khiển máy đo cũ, dongle USB hoặc máy in không hỗ trợ Windows 11, thứ gì bạn áp phía ứng dụng cũng không giải quyết. Mã chạy trong kernel, như một phần phần mềm diệt virus, cũng vậy.3
- Ứng dụng 16-bit. Windows 64-bit không hỗ trợ chạy ứng dụng 16-bit. Handle có 32 bit hợp lệ trên Windows 64-bit và không thể cắt để đưa cho ứng dụng 16-bit, nên khởi động thất bại với
ERROR_BAD_EXE_FORMAT.8 Ngay cả khi bản thân ứng dụng là 32-bit, các gói thời đó có stub trình cài đặt 16-bit tồn tại, và hiện ra thành «ứng dụng sẽ chạy, nhưng chúng ta không cài được». - Truy cập phần cứng trực tiếp. Ứng dụng công nghiệp giả định có thể chạm trực tiếp cổng I/O hoặc bộ nhớ vật lý vốn không được phép làm vậy từ user mode trên Windows hiện đại, và điều đó ngoài phạm vi shim có thể giả mạo.
- Vượt cơ chế bảo mật. Vì shim chạy dưới cùng ràng buộc bảo mật như ứng dụng, nó không thể làm «việc bạn không làm được vì thiếu quyền» trở thành có thể. ForceAdminAccess và WRPMitigation chỉ giả mạo thành công kiểm tra hoặc ghi để ứng dụng tiếp tục; chúng không thực sự viết lại tài nguyên được bảo vệ.34
- Ứng dụng tự kiểm tra tính toàn vẹn. Ứng dụng có bảo vệ sao chép cũ hoặc phát hiện giả mạo có thể coi chính hook API là bất thường rồi ngừng hoạt động.
flowchart TB
accTitle: Trường hợp shim không có tác dụng
accDescr: Shim chạy trong tiến trình user-mode, nên không có tác dụng với vấn đề trình điều khiển kernel-mode, ứng dụng 16-bit, truy cập phần cứng trực tiếp, hay vượt cơ chế bảo mật
shim["Shim (chạy ở user mode)"] -->|Không có tác dụng| drv["Trình điều khiển kernel"]
shim -->|Không có tác dụng| b16["Ứng dụng 16-bit"]
shim -->|Không có tác dụng| hw["Truy cập phần cứng trực tiếp"]
shim -->|Không có tác dụng| sec["Vượt cơ chế bảo mật"]
b16 -.-> fmt["Trên 64-bit, bản thân khởi động đã thất bại"]
sec -.-> fake["Chỉ giả mạo thành công để ứng dụng tiếp tục"]
Hình 13: Shim chỉ user-mode và không tới kernel, ứng dụng 16-bit, truy cập phần cứng trực tiếp hay vượt bảo mật.
Và giới hạn cốt yếu chung cho mọi shim là nó là biện pháp tạm. Shim là lời nói dối khít một cách dùng cụ thể của một API cụ thể, và nếu triển khai phía OS đổi, giả định sụp. Shim Microsoft cung cấp được duy trì như một phần Windows qua Windows Update,3 nhưng chăm sóc những lời nói dối bạn áp bằng cơ sở tùy chỉnh là việc của tổ chức bạn. Hãy lập ngân sách, như chi phí kéo dài tuổi thọ, một vận hành xác nhận «danh sách ứng dụng đang được shim giữ sống» ở mỗi bản cập nhật tính năng.
flowchart TB
accTitle: Shim như biện pháp tạm, và ai chịu trách nhiệm duy trì
accDescr: Shim là lời nói dối khít một cách dùng API cụ thể và giả định sụp nếu triển khai phía OS đổi; shim Microsoft được duy trì qua Windows Update, nhưng chăm sóc lời nói dối áp bằng cơ sở tùy chỉnh là việc tổ chức, và xác nhận mỗi bản cập nhật tính năng là chi phí kéo dài tuổi thọ
shim["Shim = lời nói dối tạm"] --> break["Thay đổi OS làm hỏng"]
ms["Shim Microsoft"] --> wu["Qua Windows Update"]
own["Lời nói dối cơ sở tùy chỉnh"] --> self["Tổ chức chăm sóc"]
self --> cost["Xác nhận mỗi bản cập nhật là chi phí kéo dài tuổi thọ"]
Hình 14: Trách nhiệm duy trì lời nói dối shim chia giữa bộ Microsoft cung cấp và bộ tùy chỉnh của tổ chức bạn.
8. Giá trị thực tế của RunAsInvoker — chỉ làm im yêu cầu nâng quyền
Trong các shim, cái xuất hiện nhiều nhất trong công việc IT hàng ngày là RunAsInvoker.
Một số ứng dụng nghiệp vụ cũ khai báo requireAdministrator trong manifest, hoặc bị phát hiện nhầm thành trình cài đặt từ tên hay nội dung EXE, rồi yêu cầu nâng quyền UAC mỗi lần khởi động. Nhiều cái, dù vậy, chỉ xin quản trị vì quán tính thời XP và không thực sự dùng quyền quản trị. Áp shim RunAsInvoker ghi đè cả phát hiện trình cài đặt lẫn manifest, và ứng dụng khởi động với token thừa hưởng từ tiến trình cha (= quyền người dùng chuẩn).9
flowchart TB
accTitle: Cách RunAsInvoker chặn yêu cầu nâng quyền
accDescr: Khai báo requireAdministrator trong manifest hoặc phát hiện nhầm thành trình cài đặt gây yêu cầu nâng quyền UAC lúc khởi động, nhưng áp RunAsInvoker ghi đè cả hai và ứng dụng khởi động với token thừa hưởng từ cha
manifest["Khai báo requireAdministrator"] --> shim{"RunAsInvoker được áp?"}
detect["Bị phát hiện nhầm thành trình cài đặt"] --> shim
shim -->|Không| uac["Yêu cầu nâng quyền UAC mỗi lần khởi động"]
shim -->|Có| token["Khởi động với token của cha"]
token -.-> limit["Công việc thật sự cần quản trị thất bại trong ứng dụng"]
Hình 15: RunAsInvoker chỉ ghi đè nguyên nhân yêu cầu nâng quyền; quyền không tăng.
Dù không xây .sdb trong Compatibility Administrator, bạn vẫn có thể tạm áp cùng lớp bằng biến môi trường __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'
Nếu bạn biến hai dòng đó thành tệp batch và phân phối như lối tắt, bạn có thể tránh trao quyền quản trị cục bộ cho người dùng chuẩn, và IT không còn bị gọi mỗi lần vì mật khẩu UAC. Đó là kỹ thuật tương thích làm cứng phòng thủ, đúng với quyền tối thiểu.
flowchart TB
accTitle: Hiệu quả phân phối batch RunAsInvoker
accDescr: Phân phối batch hai dòng đặt RunAsInvoker như lối tắt nghĩa là bạn có thể tránh trao quyền quản trị cục bộ cho người dùng chuẩn, IT không bị gọi vì mật khẩu UAC, và vận hành theo quyền tối thiểu
bat["Phân phối batch hai dòng"] --> noadmin["Bạn có thể tránh trao quyền quản trị"]
bat --> nocall["IT không bị gọi vì UAC"]
noadmin --> lp["Vận hành theo quyền tối thiểu"]
nocall --> lp
Hình 16: Chỉ phân phối batch cũng có thể giảm cả trao quyền quản trị lẫn bị gọi vì UAC.
Các lưu ý cũng vậy, rõ ràng.
- Quyền không tăng. Công việc thật sự cần quyền quản trị (ghi HKLM, cập nhật dưới Program Files, v.v.) sẽ lỗi trong ứng dụng, hoặc, nếu đủ điều kiện, bị ảo hóa UAC chuyển hướng sang VirtualStore.10 Nếu lưu cài đặt đột nhiên «ngừng chạy», hãy nghi ảo hóa.
- Phương pháp biến môi trường chỉ áp cho tiến trình con. Để áp vĩnh viễn, cài đặt trực tiếp trong khóa Layers (RUNASINVOKER không có mục trên tab) hoặc phân phối qua .sdb thì đáng tin.
- Sửa đích ghi mới là đường thật. Nếu bạn đổi được ứng dụng, chuyển tệp cài đặt xuống
%APPDATA%và khai báoasInvokertrong manifest — đó là hình dạng đúng.9
flowchart TB
accTitle: Áp tạm và áp vĩnh viễn RunAsInvoker
accDescr: Áp qua biến môi trường COMPAT_LAYER chỉ áp cho tiến trình con khởi động từ đó; để áp vĩnh viễn hãy cài đặt trực tiếp trong khóa Layers hoặc phân phối qua .sdb
env["Đặt qua biến môi trường"] --> child["Chỉ áp cho tiến trình con"]
child -.-> tmp["Áp tạm"]
layers["Đặt trực tiếp trong khóa Layers"] --> always["Áp vĩnh viễn"]
sdb["Phân phối qua sdb"] --> always
Hình 17: Phương pháp biến môi trường là áp tạm giới hạn tiến trình con; làm vĩnh viễn thì dùng khóa Layers hoặc .sdb.
9. Quyết định giữa kéo dài tuổi thọ và di chuyển — nghĩ gì sau khi chạy dưới shim
Khoảnh khắc chạy dưới shim là nhẹ nhõm, nhưng quan trọng là đừng dừng nghĩ ở đó. Chạy dưới shim chỉ nghĩa là nó tình cờ khớp ổ cắm Windows đã chuẩn bị. Các trục quyết định, trong bảng.
| Trục quyết định | Điều kiện nghiêng về kéo dài tuổi thọ (shim) | Điều kiện nghiêng về di chuyển / viết lại |
|---|---|---|
| Thời gian dùng còn lại | Dự định nghỉ cùng nghiệp vụ trong 1–2 năm | Giả định tiếp tục dùng 5 năm trở lên |
| Mã nguồn | Không có (nhà cung cấp mất, hoặc thất lạc) | Có, hoặc tài sản có thể khôi phục |
| Độ sâu phụ thuộc | Chỉ vấn đề tương thích API user-mode | Phụ thuộc trình điều khiển, 16-bit, hoặc phần cứng chuyên dụng |
| Lựa chọn thay thế | Không có sản phẩm đóng gói hay phiên bản mới | Sản phẩm và công nghệ đích rõ |
| Tác động khi thất bại | Nghiệp vụ chạy được trên quy trình dự phòng | Nghiệp vụ cốt lõi bị đánh trực tiếp |
| Năng lực xác nhận | Bạn xác nhận được hành vi mỗi bản cập nhật tính năng | Không có nguồn lực xác nhận, và dễ bị đóng băng |
Nếu quyết định kéo dài tuổi thọ, đưa ba điểm sau vào vận hành như một bộ.
- Ghi. EXE nào, shim/lớp nào, và vì sao. Để giá trị khóa Layers và GUID .sdb trong sổ cái. «Không ai biết vì sao nó chạy» là món nợ lớn nhất bạn để lại cho người sau. Đây cùng tư duy bảo tồn trong «When You Inherit a System With No Source Code and No Documentation».
- Xác nhận. Đưa khởi động và thao tác chính của ứng dụng đang được shim giữ sống vào mục xác nhận bản cập nhật tính năng Windows. Gắn với kế hoạch thay OS (Practical Options After Windows 10 End of Support).
- Đặt hạn. Quyết định hết hạn kéo dài — «đến lần làm mới hệ thống cốt lõi tiếp theo», «đến tháng 3 năm 2028» — và chạy song song việc cân nhắc di chuyển.
flowchart TB
accTitle: Bộ vận hành ba điểm sau khi quyết định kéo dài tuổi thọ
accDescr: Ghi vào sổ cái shim nào làm nó chạy, xác nhận hành vi ứng dụng đang được shim giữ sống mỗi bản cập nhật tính năng, đặt hạn hết kéo dài tuổi thọ, và chạy song song việc cân nhắc di chuyển
decide["Quyết định kéo dài tuổi thọ"] --> rec["Ghi: shim nào làm nó chạy, vào sổ cái"]
rec --> verify["Xác nhận: kiểm hành vi mỗi bản cập nhật tính năng"]
verify --> deadline["Hạn: quyết định hết kéo dài tuổi thọ"]
deadline --> mig["Chạy song song việc cân nhắc di chuyển"]
Hình 18: Kéo dài tuổi thọ được vận hành như bộ ba điểm ghi, xác nhận và hạn, kể cả chạy song song việc cân nhắc di chuyển.
Ở phía di chuyển, các lựa chọn chuẩn đổi theo công nghệ ứng dụng. Với VB6, lựa chọn ba hướng viết lại toàn bộ, chuyển tự động và di chuyển theo giai đoạn được sắp trong «How Long Will VB6 Apps Keep Running?»; với phụ thuộc ActiveX/OCX, bảng quyết định giữ / bọc / thay trong «How to Handle ActiveX / OCX Today». Cách đặt shim lành mạnh là mua thời gian để giai đoạn cân nhắc và chuẩn bị của dự án di chuyển đó chạy an toàn.
flowchart TB
accTitle: Lựa chọn phía di chuyển, và chỗ đứng của shim
accDescr: Các lựa chọn di chuyển chuẩn đổi theo công nghệ ứng dụng; với VB6 lựa chọn ba hướng là viết lại, chuyển tự động và di chuyển theo giai đoạn, với phụ thuộc ActiveX áp bảng giữ / bọc / thay, và shim được đặt như mua thời gian cho cân nhắc và chuẩn bị dự án di chuyển
tech{"Công nghệ ứng dụng là gì?"} -->|VB6| vb["Viết lại, chuyển tự động, hoặc di chuyển theo giai đoạn"]
tech -->|Phụ thuộc ActiveX| ax["Giữ, bọc, hoặc thay"]
shim["Kéo dài tuổi thọ qua shim"] -.->|Mua thời gian cho cân nhắc và chuẩn bị| tech
Hình 19: Các lựa chọn di chuyển chuẩn do công nghệ ứng dụng quyết định, và shim được đặt như mua thời gian cho việc cân nhắc đó.
10. Tóm tắt
- Bản sắc thật của chế độ tương thích là shim. Cài đặt từ tab Tương thích được ghi vào khóa AppCompatFlags\Layers và tiêm vào tiến trình lúc khởi động như hook API qua viết lại IAT.
- Shim là tập hợp «lời nói dối trả về câu trả lời ứng dụng cũ mong đợi». Các shim sẵn cho giả mạo phiên bản, ánh xạ lại đường dẫn, giả mạo registry, giả mạo kiểm tra quản trị và tương tự được cung cấp.
- Bản thân Windows mặc định dùng rất nhiều shim, và PCA có thể tự áp chúng. Dựa vào chế độ tương thích bản thân là lựa chọn hợp lý cưỡi trên cơ chế chính thức của OS.
- Có giới hạn nguyên tắc chỉ-user-mode và không vượt bảo mật, còn trình điều khiển kernel, ứng dụng 16-bit và truy cập phần cứng trực tiếp không cứu được.
- Triển khai tổ chức là xây .sdb tùy chỉnh trong Compatibility Administrator (Windows ADK) rồi phân phối bằng sdbinst. Chọn bản 32-bit/64-bit, kiểm tra bằng tài khoản người dùng thực tế, và quản lý cập nhật theo GUID là các điểm thực tế.
- Ứng dụng «yêu cầu quản trị nhưng thực sự không cần» có thể hạ xuống quyền chuẩn bằng
__COMPAT_LAYER=RunAsInvoker. Đó là kỹ thuật phòng thủ làm im yêu cầu nâng quyền thay vì phát quyền. - Chạy dưới shim là kéo dài tuổi thọ, không phải giải pháp. Ghi điều gì làm nó chạy, xác nhận mỗi bản cập nhật tính năng, và đặt hạn để di chuyển chạy song song — bộ ba điểm đó nằm trong quyết định «dựa vào chế độ tương thích».
Lần sau ứng dụng cũ bắt đầu chạy sau một hộp kiểm chế độ tương thích, hãy hỏi lại. «Ứng dụng này đang chạy nhờ lời nói dối nào? Lời nói dối đó còn hiệu lực bao lâu?» Nếu bạn trả lời được, kéo dài tuổi thọ là chiến lược đáng trọng.
Bài viết liên quan
- 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
- How to Handle ActiveX / OCX Today - A Keep / Wrap / Replace Decision Table
- 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
- Tích hợp shell Windows ngày nay — menu ngữ cảnh, liên kết tệp, và những gì đổi trong Windows 11
Lĩnh vực tư vấn liên quan
KomuraSoft LLC xử lý điều tra cách ứng dụng nghiệp vụ cũ không có mã nguồn hành xử và thiết kế kéo dài tuổi thọ (chọn shim và chế độ tương thích, xây và triển khai .sdb tùy chỉnh), xác nhận tương thích ứng dụng hiện có cho di chuyển Windows 11, và lập kế hoạch viết lại hoặc di chuyển chạy song song với kéo dài tuổi thọ. Tư vấn từ giai đoạn «nó bắt đầu chạy ở chế độ tương thích, nhưng để vậy có ổn không?» cũng được.
- Tái sử dụng và di chuyển tài sản hiện có
- Phát triển ứng dụng Windows
- Tư vấn kỹ thuật và đánh giá thiết kế
- Liên hệ với chúng tôi
Liên kết tham khảo
-
Microsoft Learn, Application Compatibility Database. Cơ sở hạ tầng tương thích quản lý sự cố và biện pháp trong cơ sở định dạng .sdb, đối chiếu theo thuộc tính tệp thực thi, Apphelp (hiện thông báo) và Appfix (hook API qua shim), cùng lớp tương thích (chế độ) bó vài shim và cờ. ↩ ↩2 ↩3
-
Microsoft Learn, DXGI overview. Cài đặt tương thích ứng dụng được lưu trong khóa registry HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers (lấy cài đặt tương thích DXGI làm ví dụ). ↩ ↩2
-
Microsoft Learn, Understanding and Using Compatibility Fixes. Bản sửa tương thích (shim) chuyển hướng lời gọi API bằng cách viết lại IAT (bảng địa chỉ nhập), liên kết động được xử lý bằng móc GetProcAddress, shim chịu cùng ràng buộc bảo mật như ứng dụng và không vượt cơ chế bảo mật OS, chỉ user-mode và không sửa được vấn đề trình điều khiển, bản sửa làm được bằng shim cũng làm được bằng sửa mã, các kịch bản dùng như ứng dụng hết hỗ trợ nhà cung cấp, và bản sửa tương thích Microsoft cung cấp được xuất như một phần Windows rồi cập nhật qua Windows Update. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Compatibility Fixes for Windows 10, Windows 8, Windows 7, and Windows Vista. Danh sách và mô tả các bản sửa tương thích đã biết gồm CorrectFilePaths, VirtualRegistry, ForceAdminAccess, RunAsAdmin/RunAsHighest/RunAsInvoker, WRPMitigation, EmulateGetDiskFreeSpace, GlobalMemoryStatusLie, LoadLibraryRedirect và họ VersionLie; chọn bản 32-bit/64-bit của Compatibility Administrator; và kiểm tra ở trạng thái nâng nghĩa là ảo hóa cùng chuyển hướng không hành xử như mong đợi, nên bạn nên xác nhận bằng tài khoản người dùng thực tế. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Program Compatibility Assistant scenarios for Windows 8. PCA theo dõi thực thi ứng dụng, phát hiện dấu hiệu sự cố tương thích đã biết, và đề xuất áp bản sửa khuyến nghị hoặc tự áp (PINDLL, DISABLEUSERCALLBACKEXCEPTION, VIRTUALIZEDELETE, WRPMITIGATION và tương tự), cùng áp bản sửa từ tab Tương thích và Program Compatibility Troubleshooter. ↩ ↩2
-
Microsoft Learn, GetVersionExW function. Từ Windows 8.1 giá trị GetVersionEx trả về phụ thuộc manifest, ứng dụng không được manifest cho Windows 8.1/10 được cho giá trị phiên bản Windows 8 (6.2), và khi chế độ tương thích bật thì phiên bản OS đã chọn được báo. ↩ ↩2 ↩3
-
Microsoft Learn, Targeting your application for Windows. Cách khai báo GUID OS được hỗ trợ bằng phần tử supportedOS trong mục compatibility của manifest ứng dụng, hành vi khi không có khai báo, và ứng dụng x86 32-bit tương tác không gồm trustInfo thuộc phạm vi ảo hóa tệp UAC (chuyển hướng ghi sang VirtualStore). ↩ ↩2
-
Microsoft Learn, Running 32-bit Applications. WOW64 là lớp giả lập chạy ứng dụng 32-bit trên Windows 64-bit và cô lập va chạm tệp cùng registry, và Windows 64-bit không hỗ trợ chạy ứng dụng 16-bit, khởi động thất bại với ERROR_BAD_EXE_FORMAT vì số bit hợp lệ trong handle. ↩ ↩2
-
Microsoft Learn, Using the RunAsInvoker Fix. Bản sửa tương thích RunAsInvoker khởi động ứng dụng với token thừa hưởng từ tiến trình cha, ghi đè cả phát hiện trình cài đặt lẫn xử lý manifest, được áp như cờ bộ nạp mà không chặn API, và khi bạn sửa được mã thì bản sửa đúng là khai báo asInvoker trong manifest. ↩ ↩2 ↩3
-
Microsoft Learn, Registry Virtualization. Ảo hóa registry là công nghệ tương thích chuyển hướng trong suốt các ghi toàn cục tới HKLM\Software sang VirtualStore theo người dùng, chỉ tiến trình tương tác 32-bit nằm trong phạm vi và bị tắt với tiến trình chỉ định requestedExecutionLevel trong manifest cùng tiến trình 64-bit, và được đặt như công nghệ tạm thời dự định gỡ khỏi Windows tương lai. ↩ ↩2
-
Microsoft Learn, High DPI Desktop Application Development on Windows. Ứng dụng không nhận DPI được coi như vẽ cố định 96 DPI và, trên màn hình DPI cao, Windows kéo giãn bitmap nên trông nhòe, cùng khác biệt giữa các chế độ nhận biết DPI (Unaware/System/Per-Monitor). ↩ ↩2
-
Microsoft Learn, Download and install the Windows ADK. Windows ADK gồm Compatibility Administrator và Standard User Analyzer, cùng cách nghĩ về chọn phiên bản ADK và cách tải cùng cài. ↩
-
Microsoft Learn, Compatibility Administrator User’s Guide. Compatibility Administrator cung cấp việc áp bản sửa tương thích, chế độ tương thích và thông báo AppHelp cùng tạo cơ sở tùy chỉnh, và cả bản 32-bit lẫn 64-bit được cài, bạn phải dùng bản 32-bit cho ứng dụng 32-bit và bản 64-bit cho ứng dụng 64-bit. ↩
-
Microsoft Learn, Creating a Custom Compatibility Fix in Compatibility Administrator. Bản sửa tương thích (trước đây gọi là shim) là mảnh mã nhỏ chặn lời gọi API; quy trình tạo Application Fix trong cơ sở tùy chỉnh (chỉ định tên ứng dụng, nhà cung cấp và EXE đích, chọn chế độ tương thích, chọn shim thêm, đặt điều kiện đối chiếu); và bạn nên để lại điều kiện nhận diện đúng ứng dụng đồng thời thu hẹp thông tin đối chiếu. ↩ ↩2
-
Microsoft Learn, Compatibility Fix Database Management Strategies and Deployment. Cơ sở quản lý tập trung được khuyên như chiến lược quản lý cơ sở tương thích tùy chỉnh, bản sửa tương thích nên gồm kiểm tra phiên bản (điều kiện đối chiếu) để không áp lên phiên bản mới, cài cục bộ bằng Sdbinst.exe (tùy chọn -q, -u, -g), cài phiên bản mới với cùng GUID cơ sở tự gỡ phiên bản cũ, và phương pháp phân phối qua MSI hoặc tập lệnh. ↩ ↩2 ↩3
Bài viết liên quan
Các bài viết gần đây có cùng thẻ để tìm hiểu sâu hơn những chủ đề lân cận.
API thread pool Win32 — Đồng thời mà không tạo luồng, với CreateThreadpoolWork
Bạn đang rải các lời gọi CreateThread khắp mã native? Bài viết này giải thích API thread pool Win32 được thiết kế lại từ Vista — bốn đối ...
Named pipe trong thực tiễn — IPC chuẩn của Windows, từ thiết kế đến bảo mật
Hướng dẫn thực tiễn về named pipe, cơ chế giao tiếp giữa các tiến trình chuẩn của Windows. Bài viết sắp xếp, từ nguồn gốc, việc chọn giữa...
Ứng dụng hỏng khi thức dậy từ ngủ — Sự kiện nguồn Windows và cách viết ứng dụng nghiệp vụ sống sót
Bạn mở laptop và kết nối của ứng dụng nghiệp vụ đã chết — nguyên nhân là thiết kế chưa tính đến ngủ. Bài viết này trình bày luồng thông b...
DllMain và Loader Lock — Lý do thật sự bạn bị bảo "đừng làm gì trong khởi tạo DLL"
Vì sao bạn không được gọi LoadLibrary hoặc đồng bộ với luồng khác từ DllMain. Dựa trên nguồn gốc, bài viết giải thích cách loader lock tu...
"Không phản hồi" thực sự là gì — Cách Windows quyết định ứng dụng đã treo, và cách thiết kế ứng dụng không treo
"Không phản hồi" của Windows là cơ chế trong đó hệ điều hành phán rằng một cửa sổ chưa lấy thông điệp trong 5 giây và thay nó bằng cửa sổ...
Chủ đề liên quan
Các trang này đặt chủ đề trong bối cảnh rộng hơn của dịch vụ và quyết định.
Chủ đề kỹ thuật Windows
Cổng vào phát triển Windows, điều tra lỗi và khai thác tài sản hiện có.
Dịch vụ liên quan đến chủ đề này
Bài viết liên quan trực tiếp đến các dịch vụ sau.
Phát triển ứng dụng Windows
Ứng dụng nghiệp vụ, tích hợp thiết bị và công cụ liên lạc, từ yêu cầu đến phát triển.
Câu hỏi thường gặp
Các câu hỏi thường gặp khi tư vấn về chủ đề của bài viết.
- Nếu ứng dụng bắt đầu chạy sau khi tôi tích chế độ tương thích, có nên tiếp tục dùng như vậy không?
- Để giữ hoạt động kinh doanh trong ngắn hạn, có. Chế độ tương thích là hook API user-mode gọi là shim, một cơ chế chính thức do hệ điều hành cung cấp. Tuy nhiên shim vẫn là biện pháp tạm để cho ứng dụng chạy mà không sửa nó, và một bản cập nhật OS khác có thể đổi giả định rồi làm nó hỏng lại. Ghi vào sổ cái việc nó chạy dưới chế độ tương thích, và coi bản ghi đó là một phần của quyết định viết lại ứng dụng hay kéo dài tuổi thọ có chủ đích.
- Hộp kiểm chế độ tương thích thực sự làm gì?
- Khi bạn lưu cài đặt trên tab Tương thích của hộp thoại thuộc tính, Windows ghi đường dẫn EXE đích và một giá trị như "WINXPSP3" hoặc "HIGHDPIAWARE" dưới khóa HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers. Lần EXE đó khởi động tiếp theo, bộ nạp Windows đọc giá trị và áp lớp tương thích tương ứng (một bó shim) lên tiến trình. Chế độ tương thích Windows XP, chẳng hạn, giả mạo phiên bản OS bằng cách trả về giá trị cũ từ các API truy vấn phiên bản. Bản thân OS không bị đổi; chỉ tiến trình đó được cho xem một Windows cũ giả.
- Có thể chạy ứng dụng thời 16-bit dưới chế độ tương thích trên Windows 64-bit không?
- Không. Windows 64-bit chạy ứng dụng 32-bit qua WOW64, nhưng không hỗ trợ chạy ứng dụng 16-bit, và nỗ lực khởi động thất bại với ERROR_BAD_EXE_FORMAT. Đó là giới hạn kiến trúc mà shim không thể vòng qua. Các gói cũ có stub trình cài đặt 16-bit cũng thất bại vì cùng lý do. Nếu thật sự cần, bạn phải nhìn ra ngoài chế độ tương thích — ví dụ máy ảo có Windows 32-bit.
- Tôi có thể chạy ứng dụng "không khởi động trừ khi chạy với quyền quản trị" dưới tài khoản người dùng chuẩn không?
- RunAsInvoker đáng thử. Nếu bạn chạy set __COMPAT_LAYER=RunAsInvoker tại dấu nhắc lệnh rồi khởi động ứng dụng, các yêu cầu nâng quyền từ manifest requireAdministrator hoặc từ phát hiện trình cài đặt bị chặn, và ứng dụng khởi động với cùng quyền (người dùng chuẩn) như tiến trình gọi. Với ứng dụng chỉ xin quyền quản trị mà không thực sự dùng, chỉ thế này đã có thể đưa nâng quyền ra khỏi vận hành hàng ngày. Quyền không tăng, nên công việc thật sự cần quyền quản trị sẽ thất bại bên trong ứng dụng. Chỉ áp dụng sau khi đã xác minh hành vi.
- Lấy Compatibility Administrator ở đâu?
- Nó nằm trong Windows ADK (Windows Assessment and Deployment Kit). Tải ADK từ trang Microsoft và, lúc cài, chọn các tính năng Application Compatibility Tools. Cả bản 32-bit và 64-bit đều được cài; bạn phải dùng bản 32-bit cho ứng dụng 32-bit và bản 64-bit cho ứng dụng 64-bit. Áp cơ sở dữ liệu tương thích tùy chỉnh (.sdb) bạn tạo bằng cách chạy lệnh sdbinst trên mỗi PC.