3

I have written a custom action for my WIX installer. The action´s Execute-attribute is set to deferred and Impersonate and running before InstallFinalize but it encounters a problem within this action which is the missing admin rigth. The action creates a file in the INSTALLFOLDER which is Program File (x86)

Thats my WIX code:

    <?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" 
           Name="WixTesterSetup" 
           Language="1033" 
           Version="1.0.0.0" 
           Manufacturer="WixTester" 
           UpgradeCode="77b7ed9a-5394-43e9-aecb-cd9985368ef6">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

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

    <Feature Id="Core" Title="Core" Level="1" ConfigurableDirectory="INSTALLFOLDER" />

    <UI>
      <UIRef Id="WixUI_Minimal" />
      <Publish  Dialog="ExitDialog"
                Control="Finish"
                Event="DoAction"
                Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
    </UI>

    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch Wix Tester" />
    <Property Id="WixShellEecxTarget" Value="[#WixTester.exe]" />
    <CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />

    <Binary Id="CustomActionBinary" SourceFile="$(var.RegistrationInfoCustomAction.TargetDir)$(var.RegistrationInfoCustomAction.TargetName).CA.dll"/>
    <CustomAction Id="RegistrationInfoCustomAction" BinaryKey="CustomActionBinary" DllEntry="SaveUserInfo" Execute="deferred" Impersonate="no" />

    <InstallExecuteSequence>
      <Custom Action='RegistrationInfoCustomAction' Before='InstallFinalize'>NOT Installed</Custom>
    </InstallExecuteSequence>

    <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="WixTesterSetup">
          <Component Feature="Core">
            <File Id="WixTester.exe" Source="$(var.WixTester.TargetPath)" KeyPath="yes" Checksum="yes"/>
          </Component>
        </Directory>
            </Directory>
        </Directory>

  </Product>

</Wix>

Simple custom action:

    public class CustomActions
{
    [CustomAction]
    public static ActionResult SaveUserInfo(Session session)
    {
        File.Create(System.IO.Path.Combine(session.GetTargetPath("INSTALLFOLDER"), "test.xml"));

        return ActionResult.Success;
    }
}

Not intresting WixTester:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Test Started");
        Console.ReadLine();
    }
}

enter image description here

2 Answers 2

1

Diagnose: I suspect there is something else wrong than just permissions. Please try the following:

Verbose Log File: Please create a verbose log file:

msiexec.exe /I "C:\file.msi" /QN /L*V "C:\msilog.log"

Hot Log Interpretation Tip: Search for "value 3" in the log file to find errors as explained by Rob Mensching (Wix & Orca author). MSI log files can be overwhelming otherwise.

More: How to interpret an MSI Log File (and in PDF format from WayBack).

Debugging Custom Actions: Are you attaching the debugger to the custom action in question? Please find information here: WIxsharp debug custom action in console - and a direct link to an Advanced Installer demonstration video. And a link to MSDN / Microsoft Docs.

Debugging In Short: show a message box and attach to it.


XML Files: XML files can be installed with WiX XML features and should not be generated via custom actions. You could also create the file from the application itself on launch in a location writable for the user. Here are a couple of links for the latter:

Recommendation: I do not know which approach can work for you. Recommend you generate the file via the application and save in the userprofile. One xml file per user.


Links:

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

1 Comment

Thanks for your reply. If I attach to msiexec.exe process I don´t reach my custom action.
0

The Problem was that deferred custom actions don´t have access to session["PropertyName"] the solution was to use session.CustomActionData["PORTProperty"] and pass the variables throught a custom action type 51. The new WIX code looks like:

    <?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" 
           Name="WixTesterSetup" 
           Language="1033" 
           Version="1.0.0.0" 
           Manufacturer="WixTester" 
           UpgradeCode="77b7ed9a-5394-43e9-aecb-cd9985368ef6">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

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

    <Feature Id="Core" Title="Core" Level="1" ConfigurableDirectory="INSTALLFOLDER" />

    <UI>
      <UIRef Id="WixUI_Minimal" />
      <Publish  Dialog="ExitDialog"
                Control="Finish"
                Event="DoAction"
                Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
    </UI>

    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch Wix Tester" />
    <Property Id="WixShellEecxTarget" Value="[#WixTester.exe]" />
    <CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />

    <Binary Id="CustomActionBinary" SourceFile="$(var.RegistrationInfoCustomAction.TargetDir)$(var.RegistrationInfoCustomAction.TargetName).CA.dll"/>
    <CustomAction Id="RegistrationInfoCustomAction" BinaryKey="CustomActionBinary" DllEntry="SaveUserInfo" Execute="deferred" Impersonate="no" />
    <CustomAction Id="CustomAction51" Property="RegistrationInfoCustomAction" Value="INSTALLFOLDER=[INSTALLFOLDER]" />

    <InstallExecuteSequence>
      <Custom Action="CustomAction51" Before='InstallFinalize' />
      <Custom Action='RegistrationInfoCustomAction' After='CustomAction51'>NOT Installed</Custom>
    </InstallExecuteSequence>

    <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="WixTesterSetup">
          <Component Feature="Core">
            <File Id="WixTester.exe" Source="$(var.WixTester.TargetPath)" KeyPath="yes" Checksum="yes"/>
          </Component>
        </Directory>
            </Directory>
        </Directory>

  </Product>

</Wix>

The Custom Action now looks like:

    using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Mime;
using System.Text;
using System.Windows.Forms;
using Microsoft.Deployment.WindowsInstaller;

namespace RegistrationInfoCustomAction
{
    public class CustomActions
    {
        [CustomAction]
        public static ActionResult SaveUserInfo(Session session)
        {
            File.Create(System.IO.Path.Combine(session.CustomActionData["INSTALLFOLDER"], "test.xml"));

            return ActionResult.Success;
        }
    }
}

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.