1

I am using the WixToolset 6.0 with Visual Studio 2022. I am trying to create an installer that installs the following files:

<ComponentGroup Id="ApplicationFiles" Directory="PROGRAM_FOLDER">
    <Component Id="CustomActionPOC.Dependency.dll" Guid="{F0D4FF63-0835-4E3C-8892-719F653BEA08}">
        <File Source="CustomActionPOC.Dependency.dll" KeyPath="true" />
    </Component>
    <Component Id="CustomActionPOC.exe" Guid="{20D68207-836C-4422-B179-E0C052FB8C7D}">
        <File Source="CustomActionPOC.exe" KeyPath="true" />
    </Component>
    <Component Id="CustomActionPOC.exe.config" Guid="{7B48E6A4-2AAD-4663-8E47-05F6E5733FD2}">
        <File Source="CustomActionPOC.exe.config" KeyPath="true" />
    </Component>
</ComponentGroup>

During the installation, for each file being copied, check if it already exists on the target and do the following (assume all files have a valid version number):

  • If it doesn't exist, just copy the new file
  • If it does exist, check the version.
    • If the installed file has a lower version, back it up and then copy the new file.
    • If the versions are the same, just copy the new version
    • If the installed file has a higher version, do not copy the new file and move on.

I am pretty confident I need to use a custom action to do this, so I created a CA project with one function:

[CustomAction]
public static ActionResult OnInstall(Session session)
{
     session.Log("Begin OnInstall");
} 

In my WXS file, I set it up to call the CA:

<Fragment Id="CustomActionProperties">
    <Binary Id="CADLL" SourceFile="CustomActionPOC.CustomActions.CA.dll" />
    <CustomAction Id="InstallCA" BinaryRef="CADLL" DllEntry="OnInstall" Return="check"  />
</Fragment>
...
<InstallExecuteSequence>
    <Custom Action="InstallCA" Before="InstallFiles" />
</InstallExecuteSequence>

Attaching to the process and setting a breakpoint in my C# method, it seems to be hitting the breakpoint, but I am not sure how to proceed from there. The session object has values, but I can't drill into the Component property to see the Files.

?session.Components
{WixToolset.Dtf.WindowsInstaller.ComponentInfoCollection}
    Count: 3
    Results View: Expanding the Results View will enumerate the IEnumerable
?session.Components["CustomActionPOC.Dependency.dll"]
{WixToolset.Dtf.WindowsInstaller.ComponentInfo}
    CurrentState: Local
    Name: "CustomActionPOC.Dependency.dll"
    RequestState: Unknown
?session.Components["CustomActionPOC.Dependency.dll"]

My thought pattern is that I can use the CA to traverse all files in the installer prior to anything copying over but I hit some roadblocks:

  1. Is this pattern even the way to go? That is, iterating through the files in the installer and checking against the existing files? If so, how would I pull the file info from the installer so that I can do the comparison (e.g., how would I pull the version from the file in the MSI)?
  2. If a better pattern is needed, can you please describe it or at least point me in the right direction?

I really wish it was as simple as an attribute on the File element that would function something like this:

<File Source="CustomActionPOC.Dependency.dll" KeyPath="true" CheckExists="true" Backup="C:\MyBackups\FileA.dll" CreateBackupFolder="true" Condition="VersionLessThan" />

1 Answer 1

0

I can answer this part of the question:

I really wish it was as simple as an attribute on the File element that would function something like this

The backup mechanism you are designing is not built into the Windows Installer. Therefore, it doesn't show up as an attribute on the File element in the "wxs" namespace. However, you could create an extension to the WiX language that either created a bunch of CopyFile symbols or introduced a custom action to do the work. That would go into a custom namespace, much like the ui namespace from WixToolset.UI.wixext brings in a bunch of UI functionality not built into the Windows Installer.

Hopefully that helps frame the problem better for you. It's not a trivial problem to solve. You've definitely jumped into the deep end of Windows Installer development with this requirement. :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.