Reputation: 169
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 which 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 mechanism. 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...
What am I doing wrong?
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 - unfortunately it is empty! why?
string cad = session["CustomActionData"];
Debugger.Break();
RegisterHelp(cad);
session.Log("End of custom action..");
return ActionResult.Success;
}
Upvotes: 16
Views: 23525
Reputation: 515
Example for WixSharp:
[CustomAction]
public static ActionResult RunAfterInstall(Session session)
{
System.Diagnostics.Process process = new();
process.StartInfo.FileName = string.Format("{0}\\{1}", session["INSTALLDIR"], $"\\{Definitions.AppName}.exe");
//process.StartInfo.FileName = @$"%ProgramFiles%\{Definitions.AppName}";
process.StartInfo.Arguments = "--start-notification";
//process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
process.Start();
return ActionResult.Success;
}
Upvotes: 0
Reputation: 2134
In order to add a new property to the Session object :
public static ActionResult CustomAction1(Session session)
with the installation directory path for example :
<Directory Id="ProgramFiles64Folder" Name="name">
<Directory Id="INSTALLDIR" Name="name1">
Just add a new CustomAction of type property :
<CustomAction Id="CustomAction1.SetProperty" Return="check" Property="INSTALLDIR_PROP" Value='[INSTALLDIR]' Execute='immediate' />
And add a new InstallExecuteSequence
<Custom Action='CustomAction1.SetProperty' After='CostFinalize' />
Then in the code you access this new property like this :
public static ActionResult CustomAction1(Session session)
{
session.Log("MY NEW ADDED PROPERTY " + session["INSTALLDIR_PROP"]);
return ActionResult.Success;
}
Upvotes: 0
Reputation: 4395
After several hours of struglling, the following worked for me:
string UserDefinedInstallDir = session["INSTALLDIR"];
Hope it helps somenone else!
Upvotes: 5
Reputation: 1114
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.
Upvotes: 9
Reputation: 201
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"];
Upvotes: 20
Reputation: 3667
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.
Upvotes: 2
Reputation: 492
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.
Upvotes: 1