5

I need to install my app's files to usual location like C:\Program Files\MyApp
and also need to copy several of them into custom folder in another partition
(let's say D:\CustomFolder, it's allowed to hardcode it).

Install should be silent - no gui or wizard. And alose everything should be in one *.msi file.

I can do that via CustomActions, but elegant-declarative way is preferable.

Has anyone tried this before?
Thanks.

UPDATE: Forgot to mention, that it's allowed for files that should be on separate partition to be in C:\Program Files\MyApp

alex.b
  • 4,547
  • 1
  • 31
  • 52

3 Answers3

6

Solved. The approach is:

  1. Specify custom folder where file should be put:

    <Property Id="MY_CUSTOM_DESTINATION" Value="D:\MyCustomFolder" />

  2. Put <Copy ..> directive into <File ...> which should be copied

<DirectoryRef Id="MyAppFolderThatIsInProgramFiles">
     <Component Id="MyComponent" Guid="some_guid">
      <File Id="MyFileXml" Source="MyFile.xml" KeyPath="yes" >
          <CopyFile Id="Copy_MyFileXml" DestinationProperty="MY_CUSTOM_DESTINATION"/>
      </File>
     </Component>
</DirectoryRef>

p.s. as a side-effect, file specified in <File Id="MyFileXml" ... /> will be put into both location: C:\Program Files\MyApp and D:\MyCustomFolder, but that's correct for my task.

alex.b
  • 4,547
  • 1
  • 31
  • 52
  • 1
    It's not a side effect - this is how it works and it is by design. When you nest a CopyFile under File element, this results into a record to the DuplicateFile Windows Installer table. If you nest CopyFile directly under Component element, this means you're not installign that file, but copy an external one to the specified location. I suggest you to understand the underlying Windows Installer concepts better - as a result you'll understand why WiXworks this way :) – Yan Sklyarenko Mar 28 '12 at 20:30
  • 1
    remove closing tag **DirectoryRef** – Vojta Jan 02 '18 at 10:55
1

It's against Windows Installer Best Practices to hard code directories. You can never assume there will always be a D: or even a C:. Still, customers have asked (demanded) that I install something to D:\FOO.

So, how to make the customer happy and have the install still "work" on that VM that doesn't have a D:? By redirecting the directory at install time with a custom action that only redirects it if D: is a fixed hard disk.

Also, while the CopyFile element is useful, it's not really needed because you can just author the files into components twice and smart cabing will make sure your MSI doesn't bloat up by having the File records point to the same entry in media \ cab storage.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • I have deal with product for internal usages only, and existing of `D:\MyCustomFolder`(which is well-known location shared between bunch of other products) is kind of prerequisite. I understand that hardcoded directories is bad in general, but in my case it's not a problem. – alex.b Mar 28 '12 at 11:26
  • 1
    Sorry, you haven't sold me. Your team is just adding to the technical debt and rationalizing the bad design away. – Christopher Painter Mar 28 '12 at 12:19
  • Yes, I realize that. Once it is necessary(which is certanly possible, but unlikely to happen), we'll easily pay this debt off. – alex.b Mar 28 '12 at 13:00
  • I wish hard coded directory references just wouldn't compile at all when MSI files are built. If people need such non-standard paths to install to - I would actually use some other deployment technology than MSI altogether. Or, as you suggest, for funky stuff like these unusual paths a custom action might actually be needed to deliver something that degrades gracefully or does something smart - even though custom actions are almost always undesirable. – Stein Åsmul Jan 02 '18 at 23:18
  • That's part of the degrade gracefully. If the CA fails for any reason you just ignore sync and nothing ever happened... the default directory structure applies. I don't believe in the "almost always" for people at our skill level. We've already solved 99.9% of our setup probems without resorting to custom actions. For a beginner "almost always" likely applies. – Christopher Painter Jan 03 '18 at 01:22
0

You can simply describe your disk structure under the Directory Tag:

<Property Id="DRIVE_1" Value="c:\" />
<Property Id="DRIVE_2" Value="d:\" />
<Property Id="DRIVE_3" Value="e:\" />

<Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="DRIVE_1" />
    <Directory Id="DRIVE_2" />
    <Directory Id="DRIVE_3" />
</Directory>

I wouldn't advocate hardcoding, but you get the idea.

David Martin
  • 11,764
  • 1
  • 61
  • 74
  • That's not working - `D:\ ` is invalid name, because `\ ` and `:` are not allowed. – alex.b Mar 28 '12 at 09:47
  • Did you hardcode the values? If this is the what you want then put them in properties. – David Martin Mar 28 '12 at 12:27
  • I've put values as a property to *.wxs file ``. If I'm not mistaken it's possible to override`MY_CUSTOM_DESTINATION` value by passing it as installer parameters from command line. – alex.b Mar 28 '12 at 12:43
  • 1
    Yes that's correct simply pass them in on the command line: msiexec /i misname.msi MY_CUSTOM_DESTINATION="d:\" this would be the better approach and you won't get ICE validation errors. – David Martin Mar 28 '12 at 12:55