0
votes

I have following Wix Code that is supposed to send the value of property to Custom Action Written in C#. Basically what I want is when the MSI is installed, I want to write the path of Folder where Wix installed the program in text file. I referred to this site and created code accordingly, but my Custom Action isn't working.

Following is my Wix File:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="SetupInstallFolder" Language="1033" Version="1.0.0.0" Manufacturer="LP" UpgradeCode="9e10a7d8-4ffb-493c-8318-c44ba4bc0c4c">
        <Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate />

        <Feature Id="ProductFeature" Title="SetupInstallFolder" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="SetupInstallFolder" />
            </Directory>
        </Directory>
    </Fragment>

    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <Component Id="SomeRandomEXE">
        <File Source ="G:\SarVaGYa\myworkspace\LatestLpa\lpa\lpa_c\here\src\lpa\Release\lpa.exe" />
      </Component>      
        </ComponentGroup>
    <Binary Id="SetupCA2"  src="G:\visual studio stuffs\SetupCAInstallFolder\SetupCAInstallFolder\bin\Release\SetupCAInstallFolder.CA.dll"/>
    <CustomAction Id="INSTALLFOLDERFINDER" Execute="immediate" Property="INSTALLEDPATH" Value="[INSTALLFOLDER]" />
    <InstallExecuteSequence>
      <Custom Action="INSTALLFOLDERFINDER" Sequence="2"></Custom>

    </InstallExecuteSequence>
    </Fragment>
</Wix>

I have also given my C# code that is supposed to get the value and write it in file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Deployment.WindowsInstaller;

namespace SetupCAInstallFolder
{
    public class CustomActions
    {
        [CustomAction]
        public static ActionResult InstallFolderFinder(Session session)
        {
            session.Log("Here is the SetupCAInstallFolder");
            string path = session["INSTALLEDPATH"];
            session.Log("Installed Path is " + path);
            System.IO.File.WriteAllText("F:\\pathgenerated.txt", path);
            //System.IO.File.WriteAllText(path + "installed.txt", "sdkasdkasdlkasdk");

            return ActionResult.Success;
        }
    }
}

The Wix file compiles and gives MSI that doesn't get the value of INSTALLEDPATH . If I add DllEntry="InstallFolderFinder" in CustomAction tag, it fails with error The CustomAction/@DllEntry attribute cannot coexist with a previously specified attribute on this element. The CustomAction element may only have one of the following target attributes specified at a time: DllEntry, Error, ExeCommand, JScriptCall, Script, Value, or VBScriptCall

How do I pass the value of INSTALLEDPATH to C# Custom Action?

2

2 Answers

3
votes

I have fixed the issue after stumbling around some more site. I have added the code in gist. The Wix File Code is here and the C# Custom action code is here . Basically I added two Custom tags in InstallExexuteSequeunce that first loads the dllentry and the second passes the parameter to Custom Action Written in C#.

1
votes

MSI is determining the paths between the actions CostInitialize and CostFinalize. Using hardcoded sequences is very rarely to recommend, and maybe you have chosen the wrong sequence number for this.

Try:

<InstallExecuteSequence>
   <Custom Action='INSTALLFOLDERFINDER' After='CostFinalize'></Custom> 
</InstallExecuteSequence>

I hope you are sure, INSTALLDEDPATH is your the correct property. The MSI base property for paths is `TARGETDIR.

If it still doesn't work, try a custom action type 51 with setting a property MYDUMMY on the value of [INSTALLEDPATH]. Now you can see, if at least the value is correctly written in a standard custom action not programmed.