{"id":1203,"date":"2008-01-14T13:29:51","date_gmt":"2008-01-14T13:29:51","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/heaths\/2008\/01\/14\/patch-families-in-wix-and-windows-installer\/"},"modified":"2019-02-17T15:30:06","modified_gmt":"2019-02-17T22:30:06","slug":"patch-families-in-wix-and-windows-installer","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/setup\/patch-families-in-wix-and-windows-installer\/","title":{"rendered":"Patch Families in WiX and Windows Installer"},"content":{"rendered":"<p>Patch families were <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa371628.aspx\">introduced in Windows Installer 3.0<\/a> as a means to sequence patches even if applied in any order, and to supersede previous patches. Supersedence allows for easier delta patching and allows more patches to be installed than the <a href=\"http:\/\/support.microsoft.com\/kb\/916899\">127 limit<\/a>.<\/p>\n<p>When we started developing the new patch build support in <a href=\"http:\/\/wix.sourceforge.net\">Windows Installer XML<\/a> (WiX) 3.0, we overloaded the concept of patch families to filter resources in a transform. By adding references to symbols to a PatchFamily element, that symbol and all other elements in the same fragment are left in the authoring transform. Every other difference between the target and upgrade products are removed. Effectively, this is like removing everything you didn&#8217;t specify in the target and upgrade products, then building a transform between the two databases. Using tools like <em><a href=\"http:\/\/msdn2.microsoft.com\/library\/aa370590.aspx\">PatchWiz.dll<\/a><\/em>, this was the only way to create a patch that included only a subset of changes.<\/p>\n<p>Patch families at build time are used as a logical grouping of resources. But once the patch is built, resources really belong to all patch families. Remember that a <a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/09\/01\/459561.aspx\">patch package<\/a> is really just a collection of transforms and zero or more cabinets; and that when <a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/09\/12\/464047.aspx\">applying a patch<\/a> to a product, the first applicable authoring transform is applied to a product individually. Even if a patch applies to multiple products, each product is transformed separately. If taking advantage of the multi-product transaction feature shipping in Windows Installer 4.5, installation scripts are still generated per-product and merely executed sequentially in a single transaction.<\/p>\n<p>So because patches are applied to a product individually and sequenced and superseded all in relation to that product, all patch families affect sequencing and supersedence with other patches applied to that product. Patch families are attributes of a patch, and there is no relationship in a patch package to resource changes in a transform.<\/p>\n<p>Consider product MSI<sub>a<\/sub> which contains <i>a.dll<\/i>, and product MSI<sub>b<\/sub> which contains <i>b.dll<\/i>. A patch is built that applies to both products. In the patch source file, file resource <i>a.dll<\/i> is added to patch family PF<sub>a<\/sub>, and file resource <i>b.dll<\/i> is added to patch family PF<sub>b<\/sub>. The resulting <em>.msp<\/em> patch package contains both patch families PF<sub>a<\/sub> and PF<sub>b<\/sub>. Now when that patch is applied to product MSI<sub>a<\/sub>, both patch families PF<sub>a<\/sub> and PF<sub>b<\/sub> are considered when sequencing and superseding. In a debug Windows Installer log, you can see this at the top of the log before the requested <a href=\"http:\/\/msdn2.microsoft.com\/library\/aa367459.aspx\">ACTION<\/a> is even started.<\/p>\n<p>To put it another way, the resource changes are defined in a transform to a product while the patch families are defined in a patch. Patches are sequenced with other patches for an individual product, and once the patch applicability and order are determined then the applicable transforms within those remaining patches are applied to the product in the order of the patches.<\/p>\n<p>Why is this important?<\/p>\n<p>For one reason, if you build a multi-product patch like in the example above but later build a single-product patch with just one of the patch families, the newer single-product patch will not supersede the older multi-product patch. You have to supersede all patch families in previously sequenced patches to supersede that patch. Now, effectively you&#8217;ve updated the same resources in the target product but both patches are still registered. This will likely only be a problem if you install so many patches you exceed the 127 patch limit or are trying to apply delta patches to the same file resources.<\/p>\n<p>Another reason is that if you moved <em>a.dll<\/em> to patch family PF<sub>b<\/sub> and installed the same multi-product patch to product MSI<sub>a<\/sub>, a previous patch containing only patch family PF<sub>a<\/sub> will not sequence correctly with the new patch containing only patch family PF<sub>b<\/sub>. At least one patch family must be common between patches for them to sequence correctly in relationship to each other. Moving a resource from one patch family to another effectively shrinks one patch family, and <a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2007\/05\/08\/patch-families-can-only-ever-grow.aspx\">patch families should only ever grow<\/a>; though, defining new, unique patch families is recommended for flexibility.<\/p>\n<p>So remember that patch family definitions at build time affect what changes are kept in a transform, while all patch families in a patch at install time affect sequencing and supersedence with other patches applied to a single product.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Patch families were introduced in Windows Installer 3.0 as a means to sequence patches even if applied in any order, and to supersede previous patches. Supersedence allows for easier delta patching and allows more patches to be installed than the 127 limit. When we started developing the new patch build support in Windows Installer XML [&hellip;]<\/p>\n","protected":false},"author":389,"featured_media":3843,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[20,26,64],"class_list":["post-1203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-installation","tag-msi4-5","tag-wix"],"acf":[],"blog_post_summary":"<p>Patch families were introduced in Windows Installer 3.0 as a means to sequence patches even if applied in any order, and to supersede previous patches. Supersedence allows for easier delta patching and allows more patches to be installed than the 127 limit. When we started developing the new patch build support in Windows Installer XML [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/1203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/users\/389"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/comments?post=1203"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/1203\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media\/3843"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media?parent=1203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/categories?post=1203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/tags?post=1203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}