I need to install some file to Public Documents from my merge module. I am trying to use WIX_DIR_COMMON_DOCUMENTS property, but all files installed to Program Files.
Here is my merge module source code:
<PropertyRef Id="WIX_DIR_COMMON_DOCUMENTS" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder">
<Directory Id="MirProgramFolder" Name="Data">
<Component Id="cmpData" Guid="c64db3df-1bf3-4c03-8b69-ac1adbb8bfdd">
<File Id="filData" Source="ForProgramFiles.txt"/>
</Component>
</Directory>
</Directory>
<!-- Files to install to public documents folder -->
<Directory Id="WIX_DIR_COMMON_DOCUMENTS">
<Directory Id="MirCommonDocumentsFolder" Name="MIR">
<Component Id="cmpTest" Guid="22381726-2cf0-45f0-a9a8-9703ed456ed6">
<File Id="filTest" Source="ForPublicDocs.txt"/>
</Component>
</Directory>
</Directory>
</Directory>
And here is my install project source code:
<Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="Slava Antonov" UpgradeCode="7418b1ee-fb1e-4000-995f-4cff646346c5">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<MergeRef Id="MergeModule1"/>
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject1" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Merge Id="MergeModule1" SourceFile="$(var.MergeModule1.TargetDir)MergeModule1.msm" DiskId="1" Language="1033"/>
</DirectoryRef>
</Fragment>
Why WIX_DIR_COMMON_DOCUMENTS does't works in merge module?
When you write <Directory Id="WIX_DIR_COMMON_DOCUMENTS">
in the merge module source, WiX will modularize the directory ID to prevent collisions with any existing directory IDs in the product that consumes the merge module.
You can verify this by opening the MSM file in Orca or InstEd (recommended) and have a look at the Directory
table. You will see a directory ID like WIX_DIR_COMMON_DOCUMENTS.9FE2C761_1860_4D8C_8538_352164BDC12F
. The appended GUID is the merge module ID.
Unfortunately the custom action WixQueryOsDirs
only sets the property WIX_DIR_COMMON_DOCUMENTS
instead of using the modularized directory ID, so the modularized directory ID will still point to the program files directory.
Suppress modularization for WIX_DIR_COMMON_DOCUMENTS
like this:
<PropertyRef Id="WIX_DIR_COMMON_DOCUMENTS"/>
<Property Id="WIX_DIR_COMMON_DOCUMENTS" SuppressModularization="yes"/>
You may get a few warnings when building the setup that consumes the merge module, when this setup already references WIX_DIR_COMMON_DOCUMENTS
or other directories from the WixUtilExtension. These can be safely ignored.
E. g. in my experiment I got these warnings:
C:\Users\REDACTED\source\repos\SetupProject1\SetupProject1\Product.wxs(38,0): warning LGHT1056: The Directory table contains a row with primary key(s) 'WIX_DIR_COMMON_DOCUMENTS' which cannot be merged from the merge module 'C:\Users\REDACTED\source\repos\SetupProject1\MergeModule1\bin\Debug\MergeModule1.msm'. This is likely due to collision of rows with the same primary key(s) (but other different values in other columns) between the database and the merge module.
C:\Users\REDACTED\source\repos\SetupProject1\SetupProject1\Product.wxs(38,0): warning LGHT1055: The InstallUISequence table contains an action 'WixQueryOsDirs' which cannot be merged from the merge module 'C:\Users\REDACTED\source\repos\SetupProject1\MergeModule1\bin\Debug\MergeModule1.msm'. This action is likely colliding with an action in the database that is being created. The colliding action may have been authored in the database or merged in from another merge module. If this is a standard action, it is likely colliding due to a difference in the condition for the action in the database and merge module. If this is a custom action, it should only be declared in the database or one merge module.
C:\Users\REDACTED\source\repos\SetupProject1\SetupProject1\Product.wxs(38,0): warning LGHT1055: The InstallExecuteSequence table contains an action 'WixQueryOsDirs' which cannot be merged from the merge module 'C:\Users\REDACTED\source\repos\SetupProject1\MergeModule1\bin\Debug\MergeModule1.msm'. This action is likely colliding with an action in the database that is being created. The colliding action may have been authored in the database or merged in from another merge module. If this is a standard action, it is likely colliding due to a difference in the condition for the action in the database and merge module. If this is a custom action, it should only be declared in the database or one merge module.
C:\Users\REDACTED\source\repos\SetupProject1\SetupProject1\Product.wxs(38,0): warning LGHT1056: The CustomAction table contains a row with primary key(s) 'WixQueryOsDirs' which cannot be merged from the merge module 'C:\Users\REDACTED\source\repos\SetupProject1\MergeModule1\bin\Debug\MergeModule1.msm'. This is likely due to collision of rows with the same primary key(s) (but other different values in other columns) between the database and the merge module.
C:\Users\REDACTED\source\repos\SetupProject1\SetupProject1\Product.wxs(38,0): warning LGHT1056: The Property table contains a row with primary key(s) 'SecureCustomProperties' which cannot be merged from the merge module 'C:\Users\REDACTED\source\repos\SetupProject1\MergeModule1\bin\Debug\MergeModule1.msm'. This is likely due to collision of rows with the same primary key(s) (but other different values in other columns) between the database and the merge module.
So WiX tells us that it cannot import the properties WIX_DIR_COMMON_DOCUMENTS
, SecureCustomProperties
and the custom action WixQueryOsDirs
because they already exist in the main product. This is nothing to worry about, because the components of the merge module will happily use the existing property WIX_DIR_COMMON_DOCUMENTS
.