Read a Windows help file (.chm) on a Mac, phone or Linux
You have a .chm, a program's manual, an old piece of software's help or an e-book packed as Compiled HTML Help, and the device in front of you is a Mac, a Chromebook, a Linux machine or a phone, none of which opens it. Drop it here: the title, the contents tree, the index, a search over every page, and each page with its pictures and working links.
The file is read on your device. It is not uploaded, and no script in it is run.
What it shows
- The contents tree. From the .hhc file inside, nested the way the author made it. Tap an entry to open its page; the entry for the page on screen stays marked.
- The index. Every keyword from the .hhk file, narrowed as you type. A keyword that points to several pages lists each of them, and sub-keywords sit under their keyword, as in the Windows help viewer.
- A search over every page. The text of all pages, searched for exactly what you type (capitals ignored). Each page with a match is listed with the number of matches and the words around the first one, and the matches are highlighted when you open it.
- Every page, readable. With its pictures and stylesheet taken from the same file, links between pages that work, Prev and Next in contents order, and light or dark to match your device.
- The file's details. The title; the language, from the locale ID in the header (0x0409 is US English, 0x0407 German, 0x0411 Japanese) with the code page its text is read in; the compiler named in the file; the default page; and the compression settings.
- Saving. The page on screen as one HTML file with its pictures and styles inside it; every page, picture and stylesheet as a ZIP whose pages open in any browser with their links working; or any single file from the list of everything inside.
What is inside a .chm file
A .chm is a small file system packed into one file, the format Microsoft introduced with HTML Help in 1997. It starts with a 96-byte header: the letters ITSF, the format version (3), a timestamp, the language ID (LCID) and where the directory and the content begin. The directory, after an ITSP header, is a run of chunks, usually 4,096 bytes each. PMGL chunks list every file with its name, the section it is in, and its offset and length, each number written as an ENCINT (7 bits per byte, the top bit saying another byte follows). PMGI chunks index the listing, so a reader can find one name without scanning every chunk.
Files live in one of two sections. Section 0 is stored as is and holds the container's own bookkeeping. Section 1, named MSCompressed, is every page, picture and stylesheet joined end to end and compressed with LZX, the method from Microsoft's .cab files: Huffman-coded bytes and back-references into a window of 32 KB to 2 MB (64 KB in most help files). So that a reader can open one page without unpacking the whole file, the compressor starts afresh at fixed points, usually every 64 KB of output, and a reset table records where each point lies in the compressed data. This page unpacks only the 64 KB pieces a page needs, so one page of a 30 MB manual opens quickly; a full-text search reads them all.
A record called #SYSTEM names the title, the contents file (.hhc), the index file (.hhk) and the default page. The .hhc and .hhk are ordinary HTML lists of <OBJECT type="text/sitemap"> entries. A worked example: the PuTTY 0.83 manual, putty.chm, is 367 KB and holds 586 files, 567 of them pages. Its compressed section unpacks from 337 KB to 2.6 MB in 41 pieces of 64 KB, and its index has 997 keywords.
Why a .chm often will not open, even on Windows
Windows blocks the pages of a .chm that came from the internet: the help window opens with its contents tree, but every page says “This program cannot display the webpage” or “Navigation to the webpage was canceled”. The fix there is to right-click the file, choose Properties and tick Unblock (or keep the file on a local drive, not a network share). macOS, iOS, Android and ChromeOS have no .chm viewer at all, and Linux needs a separate program such as xCHM or KchmViewer. This page uses none of them, so neither problem applies.
That blocking exists for a reason: Windows' help viewer runs a .chm's scripts and ActiveX controls with the rights of a local program, and .chm files have long been used to deliver malware. Here every script, event handler, javascript: link and ActiveX object is removed before a page is shown, and the frame it is shown in is not allowed to run scripts in any case.
Files it opens
- .chm
- Compiled HTML Help, written by Microsoft's HTML Help Workshop and by tools such as Halibut, Help & Manual, RoboHelp, Sphinx and Doxygen (through hhc.exe). Program manuals, SDK and old MSDN references, the PHP and Python manuals of their day, and e-books.
- .chi
- The index companion that large help collections split off. It is the same container and opens, but it holds index data rather than pages.
- Not opened
- WinHelp files (.hlp) from Windows 3.1 to XP, a different format; Microsoft Reader e-books (.lit) and Help 2 files (.hxs), which start with
ITOLITLSand are named as such.
What this cannot do
- Run scripts or ActiveX controls in the help file. Nothing in the file is run. Pages that build part of themselves with JavaScript (some generated API references and expandable sections) show without that part, and ActiveX buttons such as “Related topics” or program shortcuts are left out.
- Show content the file loads from the internet. Pictures, frames and stylesheets that a page fetches from a web address are blocked, and their number is shown under each page. Links to web sites are kept and open in a new tab only when you click them.
- Convert to PDF or EPUB. It saves HTML (one page, or all pages as a ZIP) and nothing else.
- Use the help compiler's own search index. The search here finds the exact text you type in each page, not word stems or synonyms, and does not rank by relevance beyond the number of matches.
- Follow links into other .chm files. Help collections split across several files link between them; those links are shown but lead nowhere here. Open the other file on its own.
- Guess a wrong code page. Pages are read in the character set they declare, or else the code page of the file's locale (Windows-1251 for Russian, Shift_JIS for Japanese). A page saved in another code page than either shows wrong letters.
- Open WinHelp .hlp, .lit or .hxs files. See above.