views:

1209

answers:

4

Hi,

new Day, new Problem;-) Still got to struggle with managed custom action. I already managed it to call an custom action and passing some test data to it. Now i want to replace the testdata with the real data i need. And here the problems starts: I want to call a batch file wich was installed in a subdirectory of my installation. Therefore i need to pass the installation path to the custom action. Afaik this can be done using the customactiondata mechnism. But this does not work. When i log the installation i can see that outside of the customaction INSTALLLOCATION is pointing to the correct path, but as soon as i look in the customaction the customactiondata property is empty...

Can anyone have a look at my code and give me a tip what i'm doing wrong? Thanks in advanvce!

Merge Module which calls the custom action:

<Module Id="DflHelpInstaller" Language="1033" Version="1.0.0.0">
 <Package Id="f952de58-1dc6-46b3-872a-7a49e2d9ea0a" Manufacturer="DflHelpInstaller" InstallerVersion="200" />

<Binary Id='RegisterDflHelpDll' SourceFile="$(var.REGISTERHELP.TargetDir)RegisterDflHelp.CA.dll" />

    <CustomAction Id='RegisterDflHelp' BinaryKey='RegisterDflHelpDll'  DllEntry='RegisterDflHelp' Execute='deferred' />

    <CustomAction Id="RegisterDflHelp.SetProperty" Return="check" Property="RegisterDflHelp" Value='[INSTALLLOCATION]' Execute='immediate' />


    <InstallExecuteSequence>
      <Custom Action='RegisterDflHelp.SetProperty' After='CostFinalize' />
      <Custom Action='RegisterDflHelp' After='InstallFiles' />
    </InstallExecuteSequence>

    <Directory Id="TARGETDIR" Name="SourceDir">
     </Directory>
    <ComponentGroupRef Id="HelpGroup"/>

    </Module>
</Wix>

Outline of the installer Project which use the MergeModule:

....

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder" SourceName="PFFiles">
<Directory Id="Company" Name='$(var.COMPANY)'>
  <Directory Id="INSTALLLOCATION" SourceName='$var.v[SDK_VERSION]'>
    <Component Id="MyBanner" Guid="C8C28B92-9326-4991-BFB1-BBDFDF3653AB">
      <File Id ="Banner.bmp" Source="Banner.bmp" KeyPath="yes" DiskId="1"/>
    </Component>
    <Merge Id ="DflHelpInstaller" SourceFile="DflHelpInstaller.msm" Language="1033" DiskId="1" />
      </Directory>
</Directory>

....

    <Feature Id="Complete" Title="Setup" Description="Installs the SDK on your local machine." Display="expand" Level="1" ConfigurableDirectory="INSTALLLOCATION">
      <ComponentRef Id="Banner" />
      <ComponentRef Id ="UNINSTALLER"/>
      <ComponentGroupRef Id="ReferenceGroup"/>
      <MergeRef Id="DflHelpInstaller"/>
</Feature>

CustomAction:

   public class CustomActions
   { 
        [CustomAction]
        public static ActionResult RegisterDflHelp(Session session)
        {
            session.Log("Begin CustomAction1");
            session.Log("Before Access to customactiondata");

            //should contain the installation path - unfortunatelly it is empty! why?
            string cad = session["CustomActionData"];
            Debugger.Break();


            RegisterHelp(cad);

            session.Log("End of custom action..");
            return ActionResult.Success;
        }
A: 

Have you tried querying the INSTALLLOCATION property directly from within the managed CA?

string cad = session["INSTALLLOCATION"];

One of the beauties of using DTF is that you have read/write access to all the MSI properties without having to use command-lines etc. So even if INSTALLLOCATION cannot be queried like a normal property you could define your own MSI property set it to the value of INSTALLOCATION and query that one inside your CA instead.

JamesD
Not if it's an "deferred" sequence, which is what he is doing. Only handful properties are available in deferred sequence.
Joey V.
+2  A: 

Your passing the value correctly but try this way to reference it.

        string[] keys = new string[session.CustomActionData.Keys.Count];
        session.CustomActionData.Keys.CopyTo(keys, 0);
        string cad = keys[0];

This should set cad to the installation path like you want it.

Scott Boettger
+1  A: 

If you delineate your data like ...

<CustomAction Id="MyCustomActionData" Return="check" Property="MyCustomAction" Value='PROPERTY0=[PROPERTY0];PROPERTY1=[PROPERTY1];PROPERTY2=[PROPERTY2]' Execute='immediate' />

You can access the data like:

string property0 = session.CustomActionData["Property0"];
string property1 = session.CustomActionData["Property1"];
string property2 = session.CustomActionData["Property2"];

In the previous example you would use:

<CustomAction Id="RegisterDflHelp.SetProperty" Return="check" Property="RegisterDflHelp" Value='INSTALLLOCATION=[INSTALLLOCATION]' Execute='immediate' />

then

string cad = session.CustomActionData["INSTALLLOCATION"];
Rick Ahlander
nice one, worked for me, thank you!
alexm
A: 

I accomplished this using the following in the .WXS file:

<Directory Id="TARGETDIR" Name="SourceDir">
 <Directory Id="ProgramFilesFolder" Name="PFiles">
  <Directory Id="ManufacturerDir" Name="Company" ShortName="Company">
   <Directory Id="INSTALLDIR" Name="TheApp">
    <Directory Id="BatchFileLocation" Name="BatchFiles">
     <Component Id="BatchFilesComp" ... >
      <File Id="SomeFile_BAT" Source="BatchFiles\SomeFile.bat" Name="SomeFile.bat" ... />
     </Component>
    </Directory>
   </Directory>
  </Directory>
 </Directory>
</Directory>

And in the custom Action:

var batchDirectory = session.GetTargetPath("BatchFileLocation");
var batchFile = batchDirectory + "SomeFile.bat"

Now, I haven't yet figured out how to avoid the duplication of the filename, but this does successfully return where the batch file was installed.

Randy Eppinger