Dassault Systèmes has not published the SolidWorks file format. Everything on this page
comes from independent reverse engineering, chiefly the open source SWFormat project
(Apache-2.0) and the older openswx reader it builds on, and it covers the container only.
The same container holds parts, assemblies (.sldasm) and drawings
(.slddrw). What the streams contain is, apart from a few XML ones, unknown;
see What is unknown.
Two container eras
| Era | How to recognise it | Container |
|---|---|---|
| Older files (before about 2015) | The file starts with D0 CF 11 E0 A1 B1 1A E1 | A Microsoft compound file (OLE2), the same container as old Word and Excel documents |
| Newer files (about 2015 onwards) | The six bytes 14 00 06 00 08 00 appear within the first 64 bytes | SolidWorks’ own chunk container, described below |
A ZIP signature (50 4B 03 04) is also tested for by SWFormat’s detector, as a
rare case. The start of the compound-file era is approximate: the sources say “before
about 2015”, not which release changed the container. The streams inside OLE2-era files are
not described here.
The chunk container (newer files)
The file is a sequence of chunks, each a header followed by the stream’s compressed data, with other bytes in between (the file header, padding, and a directory near the end). A chunk is found by searching for the marker. All integers are little-endian. Offsets in the table are from the start of the chunk, which is 4 bytes before the marker.
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0x00 | 4 | val_a | A signature that is fixed within a file; not a size |
| 0x04 | 6 | Marker | 14 00 06 00 08 00 |
| 0x0A | 1 | section_type | The kind of chunk; values are not documented |
| 0x0B | 3 | – | Not described by the sources |
| 0x0E | 4 | f1 | A flag or size field. A value of 65 536 or more together with a non-zero csz marks an inline chunk, one whose data follows its name |
| 0x12 | 4 | csz | Compressed size: length of the data after the name |
| 0x16 | 4 | usz | Uncompressed size |
| 0x1A | 4 | nsz | Length of the name in bytes |
| 0x1E | nsz | Name | The stream name, scrambled (below) |
| 0x1E + nsz | csz | Data | Raw DEFLATE data |
- Name scrambling. Each name byte is rotated left by a key, a number of
bits taken modulo 8. The key is the byte at offset 7 of the file (the eighth byte). The
result is the stream name as UTF-8, for example
docProps/custom.xml. - Compression. The data is DEFLATE (RFC 1951) with no zlib or gzip wrapper (in zlib terms, window bits −15).
- Walking. The reader scans for the marker; a hit is accepted if the name length is at most 512, csz is at most 64 MiB, the decoded name is printable ASCII, the chunk is inline and its data fits in the file. After accepting a chunk the scan jumps to the end of its data, since the marker bytes can appear by chance inside compressed data. Marker hits that are not inline chunks (f1 under 65 536, or csz 0) belong to the directory region and are not stream chunks.
The directory near the end of the file
Near the end of the file, a table of records describes each stream (its compressed and uncompressed sizes and its position). The record layout is not documented by the sources, only that it exists and that SolidWorks relies on it. Two statements about it need care:
- SWFormat’s plain-English guide says each position is stored as the real offset minus 8, and that fixing these pointers after a stream changes size lets SolidWorks reopen the file.
- The project’s own README later says that this pointer fix-up was found to be rejected by SolidWorks for files whose chunks had moved, and that it was replaced by writing the edited stream back at its original compressed size (padding it) so that no offsets shift. The minus-8 rule therefore should be treated as unproven.
A file that has the same content saved twice is not byte-identical, because timestamps, identifiers and the graphics cache are regenerated on each save.
Known streams
Stream names that SWFormat names, with what it says about them. A part has about 40 streams.
| Stream | Contents | Decoded? |
|---|---|---|
docProps/custom.xml | Custom properties (part number, material, revision and so on) as XML. SolidWorks gives this stream priority over the binary Contents/CusProps copy | Yes, as XML |
docProps/core.xml | Author, title and last-saved time | As XML |
Contents/CusProps | A binary copy of the custom properties, stored as an MFC CArchive (strings are MFC CStringW: FF FE FF, a length, then UTF-16LE) | Header and records modelled by SWFormat |
Contents/CMgrHdr2 | The configuration list | Read by SWFormat |
Config-N-Properties.xml | Properties that belong to configuration N (per the SWFormat README) | As XML |
Contents/DisplayLists | A graphics cache of the model, rebuilt on every save | No |
Contents/Definition | Part of the feature and geometry definition | No; SWFormat is reading drawing sheets and sketches from it, not parts |
Config-0-FeatureBodies/LocalBodies | The solid body geometry, described as Parasolid-flavoured binary | No |
Preview, PreviewPNG | The thumbnail image | Not described further by the sources |
_MO_VERSION_NNNNN/Biography | The edit and save history. The NNNNN in the name is the format version; a file’s version is the largest NNNNN present | No |
[Content_Types].xml, _rels/.rels | Packaging files in the style of the Open Packaging Convention | Not described |
ThirdPtyStore/… | Data kept by add-ins | No |
What is unknown
- The meaning of section_type values and of the three bytes after it, and of f1 beyond the inline test.
- The directory record layout and any checksums.
- The structure of every non-XML stream: the feature tree, sketches, bodies, display lists, history and preview of parts. The solid itself is computed by the Parasolid kernel, whose transmit format is documented separately (see Parasolid X_T), but how a part file wraps it is not known from these sources.
- The older OLE2-era streams, and exactly when the container changed.
- Whether the format differs between SolidWorks releases beyond the version number in
_MO_VERSION_NNNNN.