WiX - How to change name of a directory after installation - wix

Pretty simple question, suppose my app will be installed as
myApp
+-- bin
+-- lib
I'd like to rename "lib" to "plugins" after installation, how can i do that?
There is a MoveFiles Element that might help, but no idea how to use it.
EDIT:
The problem here is, in my case, source files could be installed into different paths, this scenario described in here.
The only way I can figure out is to create two component groups and install them conditionally. However, using heat to harvest same subdir twice will cause ID conflicting, so I'm thinking to use different paths(e.g. lib and another-lib), and then rename one of the path back after installation, so this question arised...

Don't. Install the files correctly up front. The way that the Windows Installer tracks things will fight you every step of the way. Just install the files in the correct folder from the beginning. Probably not the answer you wanted.

I finally wrote a C++ program to extend heat generated wxs with another directory structure. So we can decide which path to install under different situations. It worked just like changing name during installation.
Here is the wxs file patched by my program. Basically it creates another directory WEBIDR and different subdirs, then adds another component group webGroup for later reference by condition element.
You can do the same thing manually, but if there are thousands of files awaiting, and if they are frequently updating, maybe a program(or script) is a better choice.
<Fragment>
<DirectoryRef Id="INSTALLDIR">
<Directory Id="dirA5528701EE26FFBF346CCE20EE8ACE99" Name="bin">
<Component Id="cmpEBA9C2A32D81BA8646BD1A64DBB39DB1" Guid="{142C531A-C71C-4890-9318-0FC42026C8FC}">
<File Id="filDB56E052EC783676CEF361C0C5AA71F3" KeyPath="yes" Source="$(var.runDir)\bin\boost_date_time-vc100-mt-1_47.dll" />
</Component>
</Directory>
<Directory Id="dir3279BEF4E08D9A00D2F205F325F00A81" Name="modules">
<Component Id="cmpDECCAE13F8937500E4AC367A8EAC95F4" Guid="{85CC0C94-1BFB-4062-BC4E-FBF143921301}">
<File Id="filDD3B40D68D0437B18B1108FBA49ABC1B" KeyPath="yes" Source="$(var.runDir)\modules\HelloAPI.dll" />
</Component>
</Directory>
</DirectoryRef>
<DirectoryRef Id="WEBDIR">
<Component Id="webcmpEBA9C2A32D81BA8646BD1A64DBB39DB1" Guid="{fec110c5-a1a0-4b07-8a35-50f1af84001a}">
<File Id="webfilDB56E052EC783676CEF361C0C5AA71F3" KeyPath="yes" Source="$(var.runDir)\bin\boost_date_time-vc100-mt-1_47.dll" />
</Component>
<Directory Id="webdirpluginF4E08D9A00D2F205F325F00A81" Name="plugins">
<Component Id="webcmpDECCAE13F8937500E4AC367A8EAC95F4" Guid="{3ef79a47-7681-4991-9726-02db38c22f6d}">
<File Id="webfilDD3B40D68D0437B18B1108FBA49ABC1B" KeyPath="yes" Source="$(var.runDir)\modules\HelloAPI.dll" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="runGroup">
<ComponentRef Id="cmpEBA9C2A32D81BA8646BD1A64DBB39DB1" />
<ComponentRef Id="cmpDECCAE13F8937500E4AC367A8EAC95F4" />
</ComponentGroup>
<ComponentGroup Id="webGroup">
<ComponentRef Id="webcmpEBA9C2A32D81BA8646BD1A64DBB39DB1" />
<ComponentRef Id="webcmpDECCAE13F8937500E4AC367A8EAC95F4" />
</ComponentGroup>
</Fragment>

Related

The target file 'XXXX' is installed in 'YYYY' by two different components on an LFN system

We recently upgraded DevExpress. Since we have a custom theme, we had to upgrade the custom theme too.
That was the easy part. Now I'm trying to upgrade the setup to match the new file.
So basically, I'm changing the <File .../> of one <Component .../>:
From
<Component Id="Lib_Various_Files" Guid="9C621EB0-12E6-4D1D-8B5B-4150A76E33AA" KeyPath="yes" SharedDllRefCount="yes">
...
<File Id="DevExpress.Xpf.Themes.PreviousTheme.v17.1.dll" Name="DevExpress.Xpf.Themes.PreviousTheme.v17.1.dll" ReadOnly="yes" Vital="no" Compressed="default" DiskId="1" Source="$(var.DirLib)\PreviousTheme\DevExpress.Xpf.Themes.PreviousTheme.v17.1.dll" />
</Component>
To:
<Component Id="Lib_Various_Files" Guid="9C621EB0-12E6-4D1D-8B5B-4150A76E33AA" KeyPath="yes" SharedDllRefCount="yes">
...
<File Id="DevExpress.Xpf.Themes.OurTheme.v17.2.dll" Name="DevExpress.Xpf.Themes.OurTheme.v17.2.dll" ReadOnly="yes" Vital="no" Compressed="default" DiskId="1" Source="$(var.DirLib)\OurTheme\.td\Publish\DevExpress.Xpf.Themes.OurTheme.v17.2.dll" />
</Component>
Now I've an error in the setup, which seems to have no links to this line:
error LGHT0204: ICE30: The target file
'qgikh9i6.dll|System.Windows.Interactivity.dll' is installed in
'[TARGETDIR]\OurProduct\Bin\' by two different components on an LFN
system: 'cmpF5730C92213BA3272DDA3A5657DFF782' and 'Lib_Prism'. This
breaks component reference counting.
[D:\ws\OurProduct-Nightly\SetupWix\SetupWix\SetupWix.wixproj]
We do reference this library, in the Lib_Prism component(which is then in another Lib_Various component, that reference Lib_Prism and Lib_Various_Files, but nowhere else.
Any idea what could be the issue?
So here is the complete components list of this file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<?include ..\Common.wxi?>
<DirectoryRef Id="BIN">
<Component Id="Lib_Various_Files" Guid="9C621EB0-12E6-4D1D-8B5B-4150A76E33AA" KeyPath="yes" SharedDllRefCount="yes">
...
<File Id="DevExpress.Xpf.Themes.OurTheme.v17.2.dll" Name="DevExpress.Xpf.Themes.OurTheme.v17.2.dll" ReadOnly="yes" Vital="no" Compressed="default" DiskId="1" Source="$(var.DirLib)\OurTheme\.td\Publish\DevExpress.Xpf.Themes.OurTheme.v17.2.dll" />
</Component>
<Component Id="Lib_MicrosoftPractices" Guid="780097FD-40C9-417A-A2C3-7C2B44567BEC" KeyPath="yes" SharedDllRefCount="yes">
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll" />
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.Configuration.dll" />
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.RegistrationByConvention.dll" />
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.dll" />
</Component>
<Component Id="Lib_Prism" Guid="0F937515-2248-4CD2-B2E9-3E121FA9D743" KeyPath="yes" SharedDllRefCount="yes">
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\Prism.Core.6.3.0\lib\net45\Prism.dll" />
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\Prism.Unity.6.3.0\lib\net45\Prism.Unity.Wpf.dll" />
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\Prism.Wpf.6.3.0\lib\net45\Prism.Wpf.dll" />
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\Prism.Wpf.6.3.0\lib\net45\System.Windows.Interactivity.dll" />
</Component>
<Component Id="Lib_MvvmValidation" Guid="8681DBA1-F83D-475B-BCB8-A54A1F05FF0A" KeyPath="yes" SharedDllRefCount="yes">
<File ReadOnly="yes" DiskId="1" Source="$(var.DirPackages)\MvvmValidation.3.1.0\lib\netstandard1.0\MvvmValidation.dll" />
</Component>
<Component Id="Lib_Protobuf_Net" Guid="AEE6F4EB-78E3-4EC5-AA88-D5CC29D683D0" KeyPath="yes" SharedDllRefCount="yes">
<File ReadOnly="yes" DiskId="1" Source="$(var.DirDotfuscated)\ProtobufNet.dll" />
</Component>
</DirectoryRef>
<ComponentGroup Id="Lib_Various" >
<ComponentRef Id="Lib_MicrosoftPractices" />
<ComponentRef Id="Lib_Prism" />
<ComponentRef Id="Lib_Various_Files" />
<ComponentRef Id="Lib_MvvmValidation" />
<ComponentRef Id="Lib_Protobuf_Net" />
</ComponentGroup>
</Fragment>
</Wix>
Looking at your source file there are several problems with your component reference counting outright. You should never install several binaries with one component - it is a direct violation of the component rules. This causes exactly the kind of problems the error message indicates.
I recommend using a single file per component because that solves a plethora of possible reference count issues and upgrade problems. The shared-dll ref counters can also cause some blues I think. Do you have a legacy installer that you are trying to be compatible with? If not, then there is no reason to enable this component option - it increments the legacy SharedDLL ref-counter used by older, non-MSI installer technologies.
Now, for the issue where you change a file name in an existing component. This is also a violation of the component rules. You can not change the absolute file name of a component's key path and keep the same component GUID - this breaks component referencing. There must be a 1-to-1 correspondence between an absolute installation path and a component GUID.
The component GUID doesn't follow the file around if it moves, and the file "moves" when you change its file name (its absolute installation path has changed). There is an explanation here with an example: Change my component GUID in wix? (recommended read - decode this MSI peculiarity and things will be clearer going forward).
If you change a file name you can either:
Set your component GUIDs to auto-generate by deleting the whole GUID section in your source. The GUID will then be generated to be stable as long as the installation target path remains the same, and when you change the file name - for example - a new GUID will be generated for you auto-magically by WiX. See this answer for sample: Syntax for guids in WIX?
Set a new, hard-coded GUID yourself for the components where you change the file name that is being installed. This can be easy to forget - hence the recommended auto-magic described in point 1.
What you should actually do when file names change is to remove the old component and add a new one with the new file name. However, changing the GUID of an existing component and changing the file name has the same effect (same as deleting the old component and adding a new one).
With that said, there are bigger problems with this source as explained above. For future reliability you must split these components into one file per component. This causes interference between your old and new version and in order to clean this up, you can:
Set a totally new installation path for your project and use a single component per file from now on and you can use WiX's auto-magic component generation feature as explained above. This will work. Setting a new main installation folder "breaks the link" to "past component referencing sins".
Or you can uninstall the existing installation early during your major upgrade by moving RemoveExistingProducts early in the InstallExecuteSequence of your newest MSI version. This also wipes the slate clean of any component referencing issues and you can change your source to use one file per component going forward. If you use the MajorUpgrade element this change is easy - just set Schedule="afterInstallValidate". That should work (no time to test).
That should be it - if I have understood your scenario correctly.
Sample WiX extract for the proposed, new version:
<DirectoryRef Id="BIN">
<Component Feature="Product">
<File Source="$(var.DirLib)\OurTheme\.td\Publish\DevExpress.Xpf.Themes.OurTheme.v17.2.dll" />
</Component>
<Component Feature="Product">
<File Source="$(var.DirPackages)\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll" />
</Component>
<Component Feature="Product">
<File Source="$(var.DirPackages)\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.Configuration.dll" />
</Component>
<Component Feature="Product">
<File Source="$(var.DirPackages)\Unity.4.0.1\lib\net45\Microsoft.Practices.Unity.RegistrationByConvention.dll" />
</Component>
<...>
</DirectoryRef>
Notice the tersified source with all attributes that can be auto-generated left out and all components now containing a single file. There is also direct specification of what feature each component belongs to as an attribute of the Component element. I find that this yields the least complicated and most flexible WiX source files. Preferences vary - obviously.
I would not roll with your current "multiple binaries per component" setup going forward. There will be more trouble if you do - almost guaranteed. MSI bites back - sorry to say - there are many bear traps. MSI has aspects that border on anti-patterns. The problems are faced by almost everyone. There is a section towards the bottom here on potential anti-patterns and also on the great benefits MSI yields for corporate deployment (just for reference): How to make better use of MSI files.
I am not particularly keen on this chaotic write-up of common MSI problems, but here it is: How do I avoid common design flaws in my WiX / MSI deployment solution? Maybe it can help to avoid some very common problems.
I finally found the issue:
It appears that DevExpress bin directory packs the System.Windows.Interactivity.dll library. So before we were not copying it and we didn't had it in our Lib\DevExpress folder.
It appears that we generate a componet with all Dll contained in the Lib\DevExpress folder, and therefore the System.WIndows.Interactivity.dll was contained in 2 differents packages.
I removed it from the DevExpress folder and now everything works fine. Sorry for the trouble.

Can I use auto-generated GUIDS with a merge module?

I use auto-guids in my <Product> but can't figure out how to use them with <Module>. I only get this error:
The component X has a key file with path 'TARGETDIR\company...'.
Since this path is not rooted in one of the standard directories (like
ProgramFiles Folder), the component does not meet the criteria for
having an automatically generated guid.
Above, company is the value mapped to !(loc.ProductManufacturerFolderName).
The only problem is that's not true. My directories are rooted in ProgramFiles just like my product is and my product works fine:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="MODULEINSTALLLOCATION" Name="!(loc.ProductManufacturerFolderName)">
<Directory Id="Data" Name="Data">
All my component declarations look roughly like this:
<Component Id="DocumentationParty_Business_TestCases_v1xlsx.component" Guid="{YOURGUID-1234-1234-84B3-C595A63428AD}" MultiInstance="yes">
<File Source="../../Development/Integration/SSIS/Documentation/Party_Business_Test Cases_v1.xlsx" KeyPath="yes" Id="DocumentationParty_Business_TestCases_v1xlsx.file" />
</Component>
Breaking it is easy, you only have to change the GUID to * and the above error results. This is broken:
<Component Id="DocumentationParty_Business_TestCases_v1xlsx.component" Guid="*" MultiInstance="yes">
<File Source="../../Development/ClaimsIntegration/SSIS/Documentation/Party_Business_Test Cases_v1.xlsx" KeyPath="yes" Id="DocumentationParty_Business_TestCases_v1xlsx.file" />
</Component>
I have a .wxs file for each directory to which components will be installed. All my component-holding .wxs files have the following structure:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="DatabasePolicy_Files">
<ComponentRef Id="DatabasePolicyCreateDatabasecmdtemplate.component" />
</ComponentGroup>
<DirectoryRef Id="DataPolicy">
<Component Id="DatabasePolicyCreateDatabasecmdtemplate.component" Guid="*" MultiInstance="yes">
<File Source="../../Development/Database/Policy/CreateDatabase.cmd.template" KeyPath="yes" Id="DatabasePolicyCreateDatabasecmdtemplate.file" />
</Component>
</DirectoryRef>
</Fragment>
</Wix>
Each <ComponentGroup> is included in my master .wxs file through a <ComponentGroupRef>. This works in all my MSI projects and breaks only now that I've started working with merge modules. Also, I've tried commenting out all components except for which matches the above definition and it still breaks on the same error.
What is the problem?
I've had this similar issue myself and based on your error message it's probably the same.
Try adding a ComponentGuidGenerationSeed, that should solve your issue. The ComponentGuidGenerationSeed acts on all subfolders as well so a single one at the top-level is sufficient for all folders.
Example:
<Directory Id="DOCUMENTATIONFOLDER" Name="Documentation" ComponentGuidGenerationSeed="a9f690d3-22b3-488f-bdac-bb665c25933c"/>
http://wixtoolset.org/documentation/manual/v3/xsd/wix/directory.html
The Component Guid Generation Seed is a guid that must be used when a
Component with the generate guid directive ("*") is not rooted in a
standard Windows Installer directory (for example, ProgramFilesFolder
or CommonFilesFolder).

Decoupling Wix Component from ComponentGroup

I'm trying to generate Wix source from a custom Visual Studio extension. As such, I'd like to be able to (somehow) just add one file (plus project reference) to the Wix Project, and have the new DLLs added in to the Product.
As an example:
<Product Id="*" Name="blah" Version="..." Manufacturer="foo" UpgradeCode="...">
<Package InstallerVersion="200" ... />
<MajorUpgrade DowngradeErrorMessage="..." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="ProductFeature" Title="blah" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<!-- Custom actions, Directories, etc .... -->
</Product>
Then in separate files (which I want to be generated), I have some Fragments:
<Fragment>
<DirectoryRef Id="MYINSTALLDIR">
<Component Id="CMP_FILE1" Guid="...">
<File Id="FILE1" Source="file1.dll" Assembly=".net" KeyPath="yes" />
</Component>
</DirectoryRef>
</Fragment>
and
<Fragment>
<DirectoryRef Id="MYINSTALLDIR">
<Component Id="CMP_FILE2" Guid="...">
<File Id="FILE2" Source="file2.dll" Assembly=".net" KeyPath="yes" />
</Component>
</DirectoryRef>
</Fragment>
So far so good. The problem is that I need to tie those together with something like:
<Fragment>
<ComponentGroup Id="ProductComponents">
<ComponentRef Id="CMP_FILE1" />
<ComponentRef Id="CMP_FILE2" />
</ComponentGroup>
</Fragment>
That works, but I don't want to do that, because it requires editing of the ComponentGroup when I want to add the next file.
So I want to try to localise the information into my added file. I can live with it always being part of the same Feature.
I tried adding the Feature attribute to Component element:
<Fragment>
<DirectoryRef Id="MYINSTALLDIR">
<Component Id="CMP_FILE1" Guid="..." Feature="ProductFeature">
<File Id="FILE1" Source="file1.dll" Assembly=".net" KeyPath="yes" />
</Component>
</DirectoryRef>
</Fragment>
but that didn't seem to add the Component to the parent feature (empty Media table warning from Wix on build, and Orca confirmed it).
I also tried adding the ComponentGroup to each generated file, but of course I can't duplicate Id attributes, and unique Id just pushes the coupling problem up into Feature...
Is there a way to add a Component without editing the ComponentGroup?
No. But you could generate (rather than edit) your ComponentGroup[#Id="ProductComponents"]. The file where it is defined can be "hidden" by generating it into the obj folder and dynamically adding it to the compile. This is effectively what HarvestDirectory and the other targets that call heat do.
While your extension is adding project references and files into the project, it can also add an MSBuild Include that defines a Target with BeforeTargets="Compile". That Target can do the generation and add the generated file to the Compile ItemGroup.
You just have to have a contract that the extension will use a particular ComponentGroup Id for this purpose. (Heat uses unique names for component and file ids to prevent conflicts. I suggest you do that too, especially for "hidden" source files.)

WIX deploy two assemblies to GAC

Using WIX, and trying to install two of the same assemblies, one for .Net35 and the other .Net40. I am using two separate components, however WIX is preventing the project from compiling.
<Directory Id="GAC40" Name="GAC">
<Component Id="MyDllServicesModuleGac40Component" Guid="307675AA-8AEC-473B-A78A-FB362CCEDE2A" Win64="yes">
<File Id="MyDllNet40DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net40\MyDll.dll" />
</Component>
</Directory>
<Directory Id="GAC35" Name="GAC">
<Component Id="MyDllServicesModuleGac35Component" Guid="47E6BD1B-25CD-466D-945E-06DCF0F2A269" Win64="yes">
<File Id="MyDllNet35DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net35\MyDll.dll" />
</Component>
</Directory>
The error I receive is:
Error 29 ICE30: The target file 'MyDll.dll' is installed in '[TARGETDIR]\GAC\' by two different components on an SFN system: 'MyDllServicesModuleGac40Component.DDD7D974_FE9C_4BA3_BDD3_A1A3A23F8057' and 'MyDllServicesModuleGac35Component.DDD7D974_FE9C_4BA3_BDD3_A1A3A23F8057'. This breaks component reference counting. D:\PROJECTS\MyDll.Experimental.3.0.0\Project\MyDll\MyDll.Wix.Services\MergeModule.wxs 34 1 MyDll.Wix.Services
The installer should be able to detect that the .Net35 dll gets installed to the GAC at C:\Windows\assembly, while the .Net40 dll gets installed to the GAC at C:\Windows\Microsoft.NET\assembly.
Renaming the DLLs is not an option.
Thanks!
UPDATE
Naturally I came up with a solution just after posting, seem wrapping the components in additional elements allowed me to get this to work. Later I read Tom Blodget's post so that is correct.
<Directory Id="GAC1" Name="GAC">
<Directory Id="GAC40" Name="GAC">
<Component Id="MyDllServicesModuleGac40Component" Guid="307675AA-8AEC-473B-A78A-FB362CCEDE2A" Win64="yes">
<File Id="MyDllNet40DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net40\MyDll.dll" />
</Component>
</Directory>
</Directory>
<Directory Id="GAC2">
<Directory Id="GAC35" Name="GAC">
<Component Id="MyDllServicesModuleGac35Component" Guid="FD74504A-6FE9-488E-9086-9DAD3024B35D" Win64="yes">
<File Id="MyDllNet35DllGac" Name="MyDll.dll" KeyPath="yes" Assembly=".net" Source="..\MyDll\bin\Net35\MyDll.dll" />
</Component>
</Directory>
</Directory>
Well, hope it helps someone!
As explained by Aaron Stebner,
When you use the attribute Assembly=".net" for a file in WiX, it will
create entries in the MsiAssembly and MsiAssemblyName table for this
component and mark it as a GAC component. That means that the file
will only be installed to the GAC by this component, and it will not
install to the directory that the component is a child of. That
directory will only be used by Windows Installer to stage a copy of
that file when creating an administrative install point.
So the directories for your two components must be different since the file names are the same. If nothing else is targeted for those directories, they won't even be created. I put my GAC components under a subdirectory of my install folder:
<Directory Id="tmp_to_GAC" Name="tmp_to_GAC">
You'd need one for each GAC.

Copy file from setup location to another location in wix on install

I have created an msi setup file which includes some files in a "Sample" folder which should be copied to a temp folder. Anybody suggest how to do this?
Something like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyVendor" Name="MyVendor">
<Directory Id="INSTALLDIR" Name="MyDir">
<Component Id="MyFileId" Guid="...G1...">
<File Id="MyFileId" Name="MyFile" Source="...blabla...\MyFile" KeyPath="yes" >
</File>
</Component>
<DirectoryRef Id="TARGETDIR">
<Component Id="MyFileCopyId" Guid="...G2...">
<RemoveFile Id="MyFileRemoveId" Name="MyFile" On="install" Directory="MyCopyDir" />
<CopyFile Id="MyFileCopyId" FileId="MyFileId" DestinationDirectory="MyCopyDir" />
</Component>
<Feature Id="MyFeature" ... >
<ComponentRef Id="MyFileId" />
<ComponentRef Id="MyFileCopyId" />
The important Xml element is CopyFile. You need to create a new component that is a copy of the first one (with different ids, guids, ... of course). Both components needs to be declared in a feature.
CopyFile element is your friend. You can nest it under the original File element a number of times, depending on how many times you need to copy it. Put the correct destination folder(s) and let Windows Installer do the rest.