Multiple issues with Wix#

Apr 2, 2015 at 3:27 PM
Edited Apr 2, 2015 at 3:31 PM
Hello,

I've troubles making Wix# work as I want.
  1. Why are only a few Steps for CustomActions implemented into Wix#?
    I want to run a custom action after AppSearch but there doesn't seem to be a way for that. I might be able to use the "LaunchConditions" step, too. But I wonder why that limitation is there.
  2. I want to create cab files but wix# itself doesn't give me a way to specify a MediaTemplate. I used the "WixSourceGenerated" event to modify the xml directly and it works, but it feels dirty.
  3. I want to run a CustomAction in the InstallExecuteSequence and the InstallUISequence but it doesn't seem to work. I have set Sequence to: Sequence.InstallExecuteSequence|Sequence.InstallUISequence but it's only added to the ExecuteSequence.
Most of my issues are based on the simple fact that I want to store the Installationdirectory in the registry and retrieve it if the software is installed already for updates.

What I tried was:
Actions = new WixSharp.Action[]
{                  
   new SetPropertyAction(new Id("SET_INSTALLDIR"),"INSTALLDIR","[EXISTINGINSTALLDIR]",Return.ignore, When.After, Step.LaunchConditions,new Condition("NOT INSTALLDIR AND EXISTINGINSTALLDIR<>\"FALSE\""),Sequence.InstallExecuteSequence|Sequence.InstallUISequence)
},

Properties = new WixSharp.Property[]
{
   new RegValueProperty("EXISTINGINSTALLDIR", RegistryHive.LocalMachine,@"Software\MyApp","InstallDir","FALSE"), 

},

RegValues = new RegValue[]
{
    new RegValue(RegistryHive.LocalMachine,@"Software\MyApp","InstallDir","[INSTALLDIR]")
}
Another not related issue I have is that I have split my installer in two parts: A "Core" installation with small files for quick update and one which contains big files but doesn't need updates.

For the Core installation I used this to ignore everything below bigfiles:
new Files(source+"\\*.*", new[] { source + @"\bigfiles\**"}))
That works but "bigfiles" itself and any other folder inside it is created (with an EmpyDirectory tag). It's only ignoring the files. Is that a bug or on purpose?

Thanks for your help.
Apr 13, 2015 at 1:02 PM
Edited Apr 13, 2015 at 1:02 PM
Still the same issue even with the Predicate<string>:
                    new Dir(@"%ProgramFiles%\bla",
                        new Files("*.*", f => !f.StartsWith(bigfiles))
                    )
Gives me:
                <Directory Id="INSTALLDIR.bigfiles" Name="bigfiles">
                  <Directory Id="INSTALLDIR.bigfiles.test" Name="test">
                    <Component Id="test.EmptyDirectory" Guid="61443279-fa11-4c51-92b4-a3e18086be15">
                      <CreateFolder />
                    </Component>
                  </Directory>
                 </Directory>
Even so I excluded bigfiles it adds them as empty directory. Only the files are excluded not the directorys.
Is that on purpose or really a bug?
Coordinator
Apr 14, 2015 at 1:21 AM
Edited Apr 14, 2015 at 1:23 AM
The class "Files" was designed for a simple generation of a Wix# directory tree form the file system directory tree. Thus you create the directory tree on the build PC and just point Wix# build script to the directory and it would recreate the same tree to be deployed on the target system as the result of the msi execution. This also includes deployment of the empty directories (as in your case). It was a specific user request for this feature.

Later the class was extended to allow exclusions of the files (not folders) to allow exclusion of the temp files created by your building environment (e.g. *.pdb files) so the Release folder created by VS can be used as an input for Files constructor.

What you are trying to achieve is a very different scenario. You do not have a directory that represents the desired deployment file structure on the target system. Instead you are trying to create this stricture dynamically based on the runtime conditions. And your input is a logical "merged" directory of all possible file/subdir combinations you ever want to install.

Thus you Files is not fully compatible with your objective. In this situation you can use one of the following approaches:
  • Implement your own equivalent of WixSharp.Project.ResolveWildCards that suits your task better. It is actually quite simple (~25-30 lines of code).
  • Dynamically creates 100% accurate desired file structure by all means you have at your disposal and feed this structure to the Files constructor as the only argument: new Files(@"Release\BigFilesConfigurationDir")
  • Manually exclude empty dirs from the project after the wiled cards resolved:
var emptyDirs = project.AllDirs.Where(d => !d.Files.Any() && !d.Dirs.Any());
        
foreach (var emptyDir in emptyDirs)
    project.AllDirs
           .ForEach(d =>
            {
                if(d.Dirs.Contains(emptyDir))
                    d.Dirs = d.Dirs.Where(x => x != emptyDir).ToArray();
            });