I'm really confused about msi version numbers. Here the Version number as used for the ProductVersion in the Property table and in the Update table is restricted to having major and minor parts of 256 or less. Here the Version number as used in the File table can have major and minor parts of 65536 or less.
Is one of these wrong? Are these two "versions" completely unrelated or what?
Also, I do not understand what the following found in the description of the File table File Table means.
"Version
This field is the version string for a versioned file. This field is blank for non-versioned files. The file version entered into this field must be identical to the version of the file included with the installation package."
How is the "version of the file included with the installation package" determined? Is it for example the value of FILEVERSION in Visual Studio's VS_VERSION_INFO resource? What would it mean for some file created with NotePad or Word?
And what exactly is a "non-versioned" file? One with a FILEVERSION = 0.0.0.0 in the VS_VERSION_INFO resource? Or something else? Are all .exe files considered versioned?
Yes, MSI ProductVersion and version in MSI file table are unrelated.
Yes,
FILEVERSION
inVERSIONINFO
can be used to set the version in the MSI file table.Version terms in context
When working with MSI version, the numbers are often retrieved from
VERSIONINFO
resource (used in resource files) or .NET assembly contexts. The MSI terms might be easier to understand when compared with those:Version
AssemblyName.Version
might be comparableProduct version
PRODUCTVERSION
, a statement using the version data typeAssemblyVersion
, usingAssemblyName.Version
File version
Windows installer: is neither a property nor a data type. It is used as term to combine version string & language string. The windows installer methods Installer.FileVersion and MsiGetFileVersion ...
No "FileVersion" property exists in the MSI.
FILEVERSION
, a statement using the version data typeAssemblyFileVersionAttribute
Version number restrictions
The version data type in Windows installer - despite being a string - has the same limitations as the version data type in resource files ...
... as well as the
AssemblyName.Version
...So in case:
PRODUCTVERSION
orAssemblyVersion
are used for the MSI ProductVersion property during the build/deploy processthe developers has to heed:
VERSIONINFO
/AssemblyName.Version
(unsigned 16bit.16bit.16bit.16bit) andSo programs used in deploy processes which uses the version number of programs for their MSI setup have to heed the following limitations:
PRODUCTVERSION
/AssemblyVersion
: 8bit.8bit.16bit-1.16bit-1 (unsigned int)FILEVERSION
/AssemblyFileVersion
: 16bit-1.16bit-1.16bit-1.16bit-1 (unsigned int)Please point out weaknesses/faults of those comparisons.
Yes, FileVersions and ProductVersions are unrelated. ProductVersion is shown in Add/Remove Programs ( Programs and Features ) and is mainly used during Major Upgrade scenarios to decide what should happen.
ProductVersion Property is defined as [0-255].[0-255].[0-65535] ( 8,8,16 signed bit respectively) File Version is defined as [0-65535].[0-65535].[0-65535].[0-65535] ( 16,16,16,16 signed bit... )
Text/XML/Config/BMP ectera will be null. Typically your authoring tool (such as InstallShield) will reflect your versioned PE files (DLL,OCX,SYS,EXE...) at build time and author their version numbers into the File table automatically.
There is also an option in InstallShield called "Always Overwrite" that "version lies" to MSI at build time and tells it that your non-PE file (TXT/XML....) really has a version number ( typically 65535.0.0.0 ) this exploits the behavior in MSI that Versioned Files Trump Non-Versioned files when deciding to overwrite or not.
Tecnically an EXE can be non-versioned but that's an anti-pattern. A non-versioned file is any file that doesn't have an embedded version resource record.
Another thing to understand that is by default Windows Installer looks at the creation date and modification date of the target file when deciding if the src file should overwrite the target. If CD and MD re equal it's considered 'virgin' (my term ) and the overwrite occurs. If they are not equal it's considered 'user data' and it's not overwritten unless you do the Always Overwrite trick.
Another thing to understand is these evaluations occur at the keyfile level of the component. Any other companion files in the component ( if not following 1:1 file per component guidelines ) will follow the dirction of the key file.
Also realize there is a difference between AssemblyVersion and AssemblyFileVersion. The .NET AssemblyFileVersion attribute is what maps to the legacy FileVersion attribute. The AssemblyVersion attribute is only used for purposes of Strong Naming and MSI doesn't care about it.
Finally, google "Windows Installer Component Rules" for more information.
Please let me know if this makes sense and if you have any additional questions. You actually asked about a dozen questions in one question so I might miss something. Also please feel free to accept this answer.