From MSI to WiX, Part 5 – Custom actions: Introduction


The main page for the series is here.


 



Introduction


Although standard actions are sufficient to execute an installation in most cases, custom actions enable the author of an installation package to extend the capabilities of standard actions by including executables, dynamic-link libraries, and script.



Important: Custom actions cannot be used in the sequence tables used for advertisement: AdvtUISequence and AdvtExecuteSequence tables.



Custom action types


































































Source\Type DLL Executable JScript VBScript Special
Binary table Type 1 Type 2 Type 5 Type 6  
Copied during installation Type 17 Type 18 Type 21 Type 22  
Referencing directory   Type 34      
Referencing property   Type 50 Type 53 Type 54  
Literal code in the database     Type 37 Type 38  
Error message         Type 19
Set directory with a formatted text         Type 35
Set property with a formatted text         Type 51


Deprecated concurrent installation actions


Concurrent Installations, also called Nested Installations, is a deprecated feature of the Windows Installer. Do not use concurrent installations to install products that are intended to be released to the public.















Custom action type Description
Type 7 Concurrent installation of a product residing in the installation package.
Type 23 Concurrent installation of an installer package within the current source tree.
Type 39 Concurrent installation of an advertised installer package.


Execution scheduling options


Because a custom action can be scheduled in both the UI and execute sequence tables, and can be executed either in the service or client process, a custom action can potentially execute multiple times.


This table describes the bit flags in the Type column of the CustomAction table and their meaning:























Bit flags <CustomAction> attribute Description
0 (default) Execute=”immediate” Always execute. Action may run twice if present in both sequence tables.
msidbCustomActionTypeFirstSequence (0x100) Execute=”firstSequence” Execute once if present in both sequence tables. Skips action in execute sequence if UI sequence has run. No effect in UI sequence. Not affected by install service registration.
msidbCustomActionTypeOncePerProcess (0x200) Execute=”oncePerProcess” Execute once per process if in both sequence tables. Skips action in execute sequence if UI sequence has been run in same process, for example both run in the client process. Used to prevent actions that modify the session state, such as property and database data, from running twice.
msidbCustomActionTypeClientRepeat (0x300) Execute=”secondSequence” Execute only if running on client after UI sequence has run. The action runs only if the execute sequence is run on the client following UI sequence. May be used to provide either/or logic, or to suppress the UI-related processing if already done for the client session.


Hidden Target option


Use the following option flags to specify that the installer not write the value entered into the Target field of the CustomAction table into the log.















Bit flags <CustomAction> attribute Description
0 (default) HideTarget=”no” The installer may write the value in the Target column of the CustomAction table into the log file.
msidbCustomActionTypeHideTarget (0x2000) HideTarget=”yes” The installer is prevented from writing the value in the Target column of the CustomAction table into the log file.
The CustomActionData property is also not logged when the installer executes the custom action.
Because the installer sets the value of CustomActionData from a property with the same name as the custom action, that property must be listed in the MsiHiddenProperties property to prevent its value from appearing in the log.


In-script execution options


You can use the following option flags to specify the in-script execution of custom actions. These options copy the action code into the execution, rollback, or commit script.


Note that the msidbCustomActionTypeInScript must be included with each of these options.































Bit flags <CustomAction> attribute Description
0 (default) Execute=”immediate” Immediate custom action. Always runs in the user’s context.
msidbCustomActionTypeInScript (0x400) Execute=”deferred” Deferred custom action.
msidbCustomActionTypeRollback (0x100) Execute=”rollback” Rollback custom action.
msidbCustomActionTypeCommit (0x200) Execute=”commit” Commit custom action.
msidbCustomActionTypeNoImpersonate (0x800) Impersonate=”yes” Custom action runs in the system context.
msidbCustomActionTypeTSAware (0x4000) TerminalServerAware=”yes” Per-machine installs on Terminal Server machines will be performed in the user’s context.


Return processing options


The flags are used to specify that the main and custom action threads run synchronously (Windows Installer waits for the custom action thread to complete before resuming the main installation thread), or asynchronously (Windows Installer runs the custom action simultaneously while the main installation continues).























Bit flags <CustomAction> attribute Description
0 (default) Return=”check” A synchronous execution that fails if the exit code is not 0 (zero).
msidbCustomActionTypeContinue
(0x40)
Return=”ignore” A synchronous execution that ignores exit code and continues.
msidbCustomActionTypeAsync
(0x80)
Return=”asyncWait” An asynchronous execution that waits for exit code at the end of the sequence.
This option cannot be used with Rollback and Script custom actions.
msidbCustomActionTypeAsync +
msidbCustomActionTypeContinue
(0x0C0)
Return=”asyncNoWait” An asynchronous execution that does not wait for completion.
Execution continues after Windows Installer terminates.
This option can only be used with the EXE type custom actions.
All other types of custom actions can be asynchronous only within the install session, and must end for the installation to terminate.


Custom Action return values


The following error codes can be returned from the DLL custom action.  For EXE custom actions zero value means success and any other value indicates an error.



























Return value Numeric value Description
ERROR_FUNCTION_NOT_CALLED 1626 Action not executed.
ERROR_SUCCESS 0 Completed actions successfully.
ERROR_INSTALL_USEREXIT 1602 User terminated prematurely.
ERROR_INSTALL_FAILURE 1603 Unrecoverable error occurred.
ERROR_NO_MORE_ITEMS 259 Skip remaining actions, not an error.


Scripting Custom Action return values


Scripting custom actions must return one of the following return codes:































Return Value Value Decsription
msiDoActionStatusNoAction 0 Action not executed.
msiDoActionStatusSuccess IDOK = 1 Action completed successfully.
msiDoActionStatusUserExit IDCANCEL = 2 Premature termination by user.
msiDoActionStatusFailure IDABORT = 3 Unrecoverable error. Returned if there is an error during parsing or execution of the Jscript or VBScript.
msiDoActionStatusSuspend IDRETRY = 4 Suspended sequence to be resumed later.
msiDoActionStatusFinished IDIGNORE = 5 Skip remaining actions. Not an error.


Custom Action Type 1


Calls a dynamic link library written in C/C++ which is stored in the Binary table.


The Source column in the CustomAction table contains the key to the record in the Binary table.


The DLL is called through the entry point named in the Target column of the CustomAction table.


All return processing, execution scheduling, and in-script execution options apply.


Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 1 custom action in Wix:


<Binary Id=MyCA SourceFile=MyCA.dll/>


 


<CustomAction Id=DoSomething


              BinaryKey=MyCA


              DllEntry=DoFunction


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence>


First, we add MyCA.dll to the Binary table.


We also add a custom action of Type 1 to the CustomAction table.  BinaryKey attribute points to the <Binary> element with the custom action dll.  DllEntry attribute specifies the name of the entry point function in the dll.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 2


Calls an executable stored in the Binary table.


The Source column in the CustomAction table contains the key to the record in the Binary table.


The Target column in the CustomAction table contains the command line string for the executable.


All return processing, execution scheduling, and in-script execution options apply.


Here is how to add Type 2 custom action in Wix:


<Binary Id=MyCA SourceFile=MyCA.exe/>


 


<CustomAction Id=DoSomething


              BinaryKey=MyCA


              ExeCommand=-switch


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence>


First, we add MyCA.exe to the Binary table.


We also add a custom action of Type 2 to the CustomAction table.  BinaryKey attribute points to the <Binary> element with the custom action dll.  ExeCommand attribute specifies the command line string for the executable.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 5


Calls the JScript custom action stored in the Binary table.


The Target column in the CustomAction table contains the optional script function to execute.


All return processing, execution scheduling, and in-script execution options apply.


All scripting custom actions require the installation of the Session object.  During execution of deferred custom action, Session object may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 5 custom action in Wix:


<Binary Id=MyCA SourceFile=MyCA.js/>


 


<CustomAction Id=DoSomething


              BinaryKey=MyCA


              JScriptCall=Main


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence> 


First, we add MyCA.js to the Binary table.


We also add a custom action of Type 5 to the CustomAction table.  BinaryKey attribute points to the <Binary> element with the custom action dll.  JScriptCall attribute specifies the script function to execute.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 6


Calls the VBScript custom action stored in the Binary table.


The Target column in the CustomAction table contains the optional script function to execute.


All return processing, execution scheduling, and in-script execution options apply.


All scripting custom actions require the installation of the Session object.  During execution of deferred custom action, Session object may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 6 custom action in Wix:


<Binary Id=MyCA SourceFile=MyCA.vbs/>


 


<CustomAction Id=DoSomething


              BinaryKey=MyCA


              VBScriptCall=Main


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence> 


First, we add MyCA.vbs to the Binary table.


We also add a custom action of Type 6 to the CustomAction table.  BinaryKey attribute points to the <Binary> element with the custom action dll.  VBScriptCall attribute specifies the script function to execute.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 17


Calls a dynamic link library written in C/C++ which is installed with the application during current session.


The Source column in the CustomAction table contains the key to the record in the File table.


The DLL is called through the entry point named in the Target column of the CustomAction table.


All return processing, execution scheduling, and in-script execution options apply.


Because file is installed with the application, there are sequencing restrictions on custom action Type 17:




  • If the source file is not already installed on the computer:



    • Custom action must be sequenced after CostFinalize action because only after this action path to the file can be resolved.


  • If the source file is not already installed on the computer:



    • Deferred custom actions of this type must be sequenced after the InstallFiles action.


    • Non-deferred custom actions of this type must be sequenced after the InstallFinalize action.

Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 17 custom action in Wix:


<Directory Id=TARGETDIR Name=SourceDir>


  <Component Id=Component1


             Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


    <File Id=MyCA Name=MyCA.dll />


  </Component>


</Directory>


 


<CustomAction Id=DoSomething


              FileKey=MyCA


              DllEntry=DoFunction


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence>


First, we add MyCA.dll to the File table.


We also add a custom action of Type 17 to the CustomAction table.  FileKey attribute points to the <File> element with the custom action dll.  DllEntry attribute specifies the name of the entry point function in the dll.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 18


Calls an executable which is installed with the application during current session.


The Source column in the CustomAction table contains the key to the record in the File table.


The Target column in the CustomAction table contains the command line string for the executable.


All return processing, execution scheduling, and in-script execution options apply.


Because file is installed with the application, there are sequencing restrictions on custom action Type 18:




  • If the source file is not already installed on the computer:



    • Custom action must be sequenced after CostFinalize action because only after this action path to the file can be resolved.


  • If the source file is not already installed on the computer:



    • Deferred custom actions of this type must be sequenced after the InstallFiles action.


    • Non-deferred custom actions of this type must be sequenced after the InstallFinalize action.

Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 18 custom action in Wix:


<Directory Id=TARGETDIR Name=SourceDir>


  <Component Id=Component1


             Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


    <File Id=MyCA Name=MyCA.exe />


  </Component>


</Directory>


 


<CustomAction Id=DoSomething


              FileKey=MyCA


              ExeCommand=-switch


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence>


First, we add MyCA.exe to the File table.


We also add a custom action of Type 18 to the CustomAction table.  FileKey attribute points to the <File> element with the custom action dll.  ExeCommand attribute specifies the command line string for the executable.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 19


This custom action displays a specified error message, returns failure, and then terminates the installation.


The value of columns in the CustomAction table:




  • Source:  must be blank.


  • Target:  Contains possibly formatted text which will be evaluated to the error message:



    • Text which is not enclosed in square brackets:



      • Text evaluates to integer:  Used as an index to the record in the Error table with the error message.


      • Contains the error message.


    • Text in square brackets will be evaluated further:



      • [Property]


      • [%EnvironmentVariable]


      • [#FilePath]


      • [$ComponentDirectoryPath]

None of the return processing, execution scheduling, and in-script execution options apply.


Here is an example of custom action Type 19 in Wix:


<CustomAction Id=IsPrivileged Error=You must be an admin to install this product />


 


<InstallExecuteSequence>


  <Custom Action=IsPrivileged Before=LaunchConditions>


    Not Privileged


  </Custom>


</InstallExecuteSequence>



Custom Action Type 21


Calls the JScript custom action which is installed with the application during current session.


The Source column in the CustomAction table contains the key to the record in the File table.


The Target column in the CustomAction table contains the optional script function to execute.


All return processing, execution scheduling, and in-script execution options apply.


Because file is installed with the application, there are sequencing restrictions on custom action Type 21:




  • If the source file is not already installed on the computer:



    • Custom action must be sequenced after CostFinalize action because only after this action path to the file can be resolved.


  • If the source file is not already installed on the computer:



    • Deferred custom actions of this type must be sequenced after the InstallFiles action.


    • Non-deferred custom actions of this type must be sequenced after the InstallFinalize action.

Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 21 custom action in Wix:


<Directory Id=TARGETDIR Name=SourceDir>


  <Component Id=Component1


             Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


    <File Id=MyCA Name=MyCA.js />


  </Component>


</Directory>


 


<CustomAction Id=DoSomething


              FileKey=MyCA


              JScriptCall=Main


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence>


First, we add MyCA.js to the File table.


We also add a custom action of Type 21 to the CustomAction table.  FileKey attribute points to the <File> element with the custom action dll.  JScriptCall attribute specifies the script function to execute.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 22


Calls the VBScript custom action which is installed with the application during current session.


The Source column in the CustomAction table contains the key to the record in the File table.  The Target column in the CustomAction table contains the optional script function to execute.  All return processing, execution scheduling, and in-script execution options apply.


Because DLL is installed with the application, there are sequencing restrictions on custom action Type 22:




  • If the source file is not already installed on the computer:



    • Custom action must be sequenced after CostFinalize action because only after this action path to the file can be resolved.


  • If the source file is not already installed on the computer:



    • Deferred custom actions of this type must be sequenced after the InstallFiles action.


    • Non-deferred custom actions of this type must be sequenced after the InstallFinalize action.

Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 22 custom action in Wix:


<Directory Id=TARGETDIR Name=SourceDir>


  <Component Id=Component1


             Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


    <File Id=MyCA Name=MyCA.vbs />


  </Component>


</Directory>


 


<CustomAction Id=DoSomething


              FileKey=MyCA


              VBScriptCall=Main


              Execute=deferred


              Return=check


              HideTarget=no


              Impersonate=no />


 


<InstallExecuteSequence>


  <Custom Action=DoSomething Before=InstallFinalize />


</InstallExecuteSequence>


First, we add MyCA.vbs to the File table.


We also add a custom action of Type 22 to the CustomAction table.  FileKey attribute points to the <File> element with the custom action dll.  VBScriptCall attribute specifies the script function to execute.


The last thing to do is to schedule our custom action in all required sequence tables.



Custom Action Type 34


Calls an executable which already exists on the target system and is not installed with the application during current session.


The Source column in the CustomAction table contains the key to the record in the Directory table.  This record is used to resolve the full path to a working directory.  This is not required to be the path to the directory containing the executable.


The Target column in the CustomAction table contains the full path and name of the executable file followed by optional arguments to the executable.  The full path and name to the executable file is required. Quotation marks must be used around long file names or paths. The value is treated as formatted text and may contain references to properties, files, directories, or other formatted text attributes.


All return processing, execution scheduling, and in-script execution options apply.


Here is how to add Type 34 custom action in Wix:


<?xml version=1.0 encoding=UTF-8?>


<Wix xmlns=http://schemas.microsoft.com/wix/2003/01/wi>


 


  <Product Id={0BD4334D-F9FE-4B70-8070-917288A50B51}


           Name=Minimal Windows Installer Sample


           Language=1033


           Codepage=1252


           Version=1.0.0


           Manufacturer=Acme Corporation


           UpgradeCode={770C5598-A538-4D44-8C2E-B2D94E15CC98}>


 


    <Package Id={E1782FB0-3D87-4B13-88DC-62E11FB72552}


             Description=Minimal Windows Installer Sample


             Comments=This installer database contains the logic and data required to install [ProductName].


             InstallerVersion=200


             Languages=1033


             SummaryCodepage=1252


             Platforms=Intel


             ReadOnly=no


             Compressed=yes


             AdminImage=no


             Keywords=Installer


             ShortNames =no


             Manufacturer=Acme Corporation />


 


    <Media Id=1 Cabinet=CAB001.cab EmbedCab=yes />


 


    <Directory Id=TARGETDIR Name=SourceDir>


      <Directory Id=ProgramFilesFolder>


        <Directory Id=INSTALLDIR Name=Minimal LongName=MinimalInstallation>


 


          <Component Id=Component1


                     Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


            <File Id=ReadMe DiskId=1 Name=Readme.txt Source=Readme.txt Vital=yes KeyPath=yes />


          </Component>


 


        </Directory>


      </Directory>


    </Directory>


 


    <CustomAction Id=ShowReadMe


                  Directory=INSTALLDIR


                  ExeCommand=[SystemFolder]notepad.exe [#ReadMe]


                  Return=asyncNoWait />


 


    <InstallExecuteSequence>


      <Custom Action=ShowReadMe After=InstallFinalize>Not Installed</Custom>


    </InstallExecuteSequence>


 


    <Feature Id=Feature1


             Title=Feature1 title


             Description=Feature1 description


             Level=1


             ConfigurableDirectory=INSTALLDIR >


      <ComponentRef Id=Component1 />


    </Feature>


 


  </Product>


</Wix>


Here we are installing the ReadMe.txt file and using the custom action to show it’s content in the notepad after installation is done.



Custom Action Type 35


Sets the target path and associated property of a record in the Directory table from a formatted text string.


The Source column in the CustomAction table contains the key to the record in the Directory table.


The Target column in the CustomAction table contains a formatted text and may contain references to properties, files, directories, or other formatted text attributes.


Only execution scheduling options apply.


Here is how to add Type 35 custom action in Wix:


<CustomAction Id=SetMergeModulesPath


              Directory=MERGEDIR


              Value=[ProgramFilesFolder]Common Files\Merge Modules />


 


<InstallExecuteSequence>


  <Custom Action=SetMergeModulesPath After=CostFinalize>Not Installed</Custom>


</InstallExecuteSequence>



Important:  Do not change the location of a target directory during maintenance installation.



Custom Action Type 37


Calls the JScript custom action stored internally in the CustomAction table.


The Source column in the CustomAction table contains the null value.


The Target column in the CustomAction table contains the script code for the custom action as a string of literal script text.


All return processing, execution scheduling, and in-script execution options apply.


Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 37 custom action in Wix:


<CustomAction Id=CopyReadMe


              Script=jscript>


  <![CDATA[


  var fso = new ActiveXObject(“Scripting.FileSystemObject”);


  var path = Session.Property(“INSTALLDIR”);


  fso.CopyFile(path + “ReadMe.txt”, path + “ReadMe2.txt”);


  ]]>


</CustomAction>


 


<InstallExecuteSequence>


  <Custom Action=CopyReadMe After=InstallFinalize>Not Installed</Custom>


</InstallExecuteSequence>



Custom Action Type 38


Calls the VBScript custom action stored internally in the CustomAction table.


The Source column in the CustomAction table contains the null value.


The Target column in the CustomAction table contains the script code for the custom action as a string of literal script text.


All return processing, execution scheduling, and in-script execution options apply.


Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 38 custom action in Wix:


<?xml version=1.0 encoding=UTF-8?>


<Wix xmlns=http://schemas.microsoft.com/wix/2003/01/wi>


 


  <Product Id={94A35E02-D48F-48F1-AC1A-23F62489BBF4}


           Name=Minimal Windows Installer Sample


           Language=1033


           Codepage=1252


           Version=1.0.0


           Manufacturer=Acme Corporation


           UpgradeCode={74069BA4-1D1C-4252-A074-B2EC0C746403}>


 


    <Package Id={????????-????-????-????-????????????}


             Description=Minimal Windows Installer Sample


             Comments=This installer database contains the logic and data required to install [ProductName].


             InstallerVersion=200


             Languages=1033


             SummaryCodepage=1252


             Platforms=Intel


             ReadOnly=no


             Compressed=yes


             AdminImage=no


             Keywords=Installer


             ShortNames =no


             Manufacturer=Acme Corporation />


 


    <Media Id=1 Cabinet=CAB001.cab EmbedCab=yes />


 


    <Directory Id=TARGETDIR Name=SourceDir>


      <Directory Id=ProgramFilesFolder>


        <Directory Id=INSTALLDIR Name=Minimal LongName=MinimalInstallation>


 


          <Component Id=Component1


                     Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


            <File Id=ReadMe DiskId=1 Name=Readme.txt Source=Readme.txt Vital=yes KeyPath=yes />


            <RemoveFile Id=RemoveCopy Name=ReadMe2.txt On=uninstall />


          </Component>


 


        </Directory>


      </Directory>


    </Directory>


 


    <CustomAction Id=CopyReadMe


                  Script=vbscript>


      <![CDATA[


      Set fso = CreateObject(“Scripting.FileSystemObject”)


      path = Session.Property(“INSTALLDIR”)


      fso.CopyFile path & “ReadMe.txt”, path & “ReadMe2.txt”


      ]]>


    </CustomAction>


 


    <InstallExecuteSequence>


      <Custom Action=CopyReadMe After=InstallFinalize>Not Installed</Custom>


    </InstallExecuteSequence>


 


    <Feature Id=Feature1


             Title=Feature1 title


             Description=Feature1 description


             Level=1


             ConfigurableDirectory=INSTALLDIR >


      <ComponentRef Id=Component1 />


    </Feature>


 


  </Product>


</Wix>



Custom Action Type 50


Calls an executable launched with a command line.  Path and file name of the executable is stored in the property.  Typical use for this custom action is to find the installation path for the executable using registry search first.


The Source column in the CustomAction table contains a key to the Property table for a property that contains the full path to the executable file..


The Target column in the CustomAction table contains the command line string for the executable identified in the Source column.


All return processing, execution scheduling, and in-script execution options apply.


Here is how to add Type 50 custom action in Wix:


<!– Find Zune’s installation path –>


<Property Id=ZUNEFOLDER>


  <RegistrySearch Id=ZuneReg


                  Root=HKLM


                  Key=SOFTWARE\Microsoft\Zune


                  Name=Installation Directory


                  Type=raw />


</Property>


 


<!– Set the property to the <path>\Zune.exe –>


<CustomAction Id=SetZunePath


              Property=ZunePath


              Value=[ZUNEFOLDER]Zune.exe />


 


<!– Custom action to start the executable –>


<CustomAction Id=StartZune


              Property=ZunePath


              ExeCommand=“”


              Return=asyncNoWait />


 


<InstallExecuteSequence>


  <Custom Action=SetZunePath After=AppSearch>ZUNEFOLDER</Custom>


  <Custom Action=StartZune After=InstallFinalize>ZUNEFOLDER And Not Installed</Custom>


</InstallExecuteSequence>



Custom Action Type 51


Sets  the property’s value from a formatted text string.


Replaceable parameters in the formatted text string are enclosed in the square brackets:




  • […] – Property


  • [%…] – Environment variable


  • [#…] – File path


  • [$…] – Component directory path 

Only execution scheduling options apply.


Here is how to add Type 51 custom action in Wix:


<!– Find Zune’s installation path –>


<Property Id=ZUNEFOLDER>


  <RegistrySearch Id=ZuneReg


                  Root=HKLM


                  Key=SOFTWARE\Microsoft\Zune


                  Name=Installation Directory


                  Type=raw />


</Property>


 


<!– Set the property to the <path>\Zune.exe –>


<CustomAction Id=SetZunePath


              Property=ZunePath


              Value=[ZUNEFOLDER]Zune.exe />



Custom Action Type 53


Calls the JScript custom action stored in the property.


The Source column in the CustomAction table contains a property name or a key to the Property table for a property containing the script text.


The Target column in the CustomAction table contains an optional script function name to be called.


All return processing, execution scheduling, and in-script execution options apply.


Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 53 custom action in Wix:


<?xml version=1.0 encoding=UTF-8?>


<Wix xmlns=http://schemas.microsoft.com/wix/2003/01/wi>


 


  <Product Id={A28D84A5-1DFB-4F2F-8CB5-C2D7764C697F}


           Name=Minimal Windows Installer Sample


           Language=1033


           Codepage=1252


           Version=1.0.0


           Manufacturer=Acme Corporation


           UpgradeCode={3E339FF5-0E8F-47F2-AB8B-3F800A46C69A}>


 


    <Package Id={????????-????-????-????-????????????}


             Description=Minimal Windows Installer Sample


             Comments=This installer database contains the logic and data required to install [ProductName].


             InstallerVersion=200


             Languages=1033


             SummaryCodepage=1252


             Platforms=Intel


             ReadOnly=no


             Compressed=yes


             AdminImage=no


             Keywords=Installer


             ShortNames =no


             Manufacturer=Acme Corporation />


 


    <Media Id=1 Cabinet=CAB001.cab EmbedCab=yes />


 


    <Directory Id=TARGETDIR Name=SourceDir>


      <Directory Id=ProgramFilesFolder>


        <Directory Id=INSTALLDIR Name=Minimal LongName=MinimalInstallation>


 


          <Component Id=Component1


                     Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


            <File Id=ReadMe DiskId=1 Name=Readme.txt Source=Readme.txt Vital=yes KeyPath=yes />


            <RemoveFile Id=RemoveCopy Name=ReadMe2.txt On=uninstall />


          </Component>


 


        </Directory>


      </Directory>


    </Directory>


 


    <Property Id=CopyProgram>


      <![CDATA[


      function main()


      {


        var fso = new ActiveXObject(“Scripting.FileSystemObject”);


        var path = Session.Property(“INSTALLDIR”);


        fso.CopyFile(path + “ReadMe.txt”, path + “ReadMe2.txt”);


      }


      ]]>


    </Property>


   


    <CustomAction Id=CopyReadMe


                  JScriptCall=main


                  Property=CopyProgram>


    </CustomAction>


 


    <InstallExecuteSequence>


      <Custom Action=CopyReadMe After=InstallFinalize>Not Installed</Custom>


    </InstallExecuteSequence>


 


    <Feature Id=Feature1


             Title=Feature1 title


             Description=Feature1 description


             Level=1


             ConfigurableDirectory=INSTALLDIR >


      <ComponentRef Id=Component1 />


    </Feature>


 


  </Product>


</Wix>



Custom Action Type 54


Calls the VBScript custom action stored in the property.


The Source column in the CustomAction table contains a property name or a key to the Property table for a property containing the script text.


The Target column in the CustomAction table contains an optional script function name to be called.


All return processing, execution scheduling, and in-script execution options apply.


Entry point to the custom action receives the handle to the installation session.  During execution of deferred custom action, session may no longer exist.  To get the value of properties use CustomActionData property.


Here is how to add Type 54 custom action in Wix:


<?xml version=1.0 encoding=UTF-8?>


<Wix xmlns=http://schemas.microsoft.com/wix/2003/01/wi>


 


  <Product Id={C02C2DF1-F74E-4C61-8D19-151D9E70D64B}


           Name=Minimal Windows Installer Sample


           Language=1033


           Codepage=1252


           Version=1.0.0


           Manufacturer=Acme Corporation


           UpgradeCode={59F2FD01-3932-4F33-882B-6A6E1E2FE0CF}>


 


    <Package Id={????????-????-????-????-????????????}


             Description=Minimal Windows Installer Sample


             Comments=This installer database contains the logic and data required to install [ProductName].


             InstallerVersion=200


             Languages=1033


             SummaryCodepage=1252


             Platforms=Intel


             ReadOnly=no


             Compressed=yes


             AdminImage=no


             Keywords=Installer


             ShortNames =no


             Manufacturer=Acme Corporation />


 


    <Media Id=1 Cabinet=CAB001.cab EmbedCab=yes />


 


    <Directory Id=TARGETDIR Name=SourceDir>


      <Directory Id=ProgramFilesFolder>


        <Directory Id=INSTALLDIR Name=Minimal LongName=MinimalInstallation>


 


          <Component Id=Component1


                     Guid={EB3E1A26-CA6C-4143-BCFA-C9CD8BFD363C}>


            <File Id=ReadMe DiskId=1 Name=Readme.txt Source=Readme.txt Vital=yes KeyPath=yes />


            <RemoveFile Id=RemoveCopy Name=ReadMe2.txt On=uninstall />


          </Component>


 


        </Directory>


      </Directory>


    </Directory>


 


    <Property Id=CopyProgram>


      <![CDATA[


      Function Main()


        Set fso = CreateObject(“Scripting.FileSystemObject”)


        path = Session.Property(“INSTALLDIR”)


        fso.CopyFile path & “ReadMe.txt”, path & “ReadMe2.txt”


        Main = 1


      End Function


      ]]>


    </Property>


   


    <CustomAction Id=CopyReadMe


                  VBScriptCall=Main


                  Property=CopyProgram />


 


    <InstallExecuteSequence>


      <Custom Action=CopyReadMe After=InstallFinalize>Not Installed</Custom>


    </InstallExecuteSequence>


 


    <Feature Id=Feature1


             Title=Feature1 title


             Description=Feature1 description


             Level=1


             ConfigurableDirectory=INSTALLDIR >


      <ComponentRef Id=Component1 />


    </Feature>


 


  </Product>


</Wix>

Comments (5)

  1. Simon Reid says:

    Hi Alex,

    I’m trying to get a custom action type 2 working but it keeps failing with error 1721. Do you have any idea why this is? Here is my code.

    Thanks in advance.

    <Binary Id="MyCA" SourceFile="C:tempMyCA.bat"/>

    <CustomAction Id="DoSomething" BinaryKey="MyCA" ExeCommand="" Execute="deferred" Return="check" Impersonate="no" />

    <InstallExecuteSequence>

     <Custom Action="DoSomething" After="InstallFiles" />

    </InstallExecuteSequence>

  2. Alex Shevchuk says:

    Usually, error 1721 means either problem with the script or some sort of permission issue.

    Your custom action is deferred, non-impersonated action, so it runs elevated under Local System account on Vista.

    Things I would check:

    – MyCA.bat is runnable outside of the installer (does not have any spelling/wrong commands issues)

    – Script in MyCA.bat does not access any network resources

    – Just in case, run installation from command prompt which is started under Administrator privileges

    – If you use Vista, try to turn off UAC

    – Try to disable anti-virus software (if computer is running any)

    Sorry, you will have to debug this issue.  There is no definite answer for this error code.

    Alex

  3. alex says:

    Hm… I want to call this command line after installation:

    echo hello> echo_test.txt

    What should I do?

  4. Hung Nguyen says:

    This article is excellent. Thanks much

  5. Aditya Kumar says:

    Hi Alex, I am trying to execute database scripts either on SQL server or Oracle ( based on the Combo box item selection ) through WIX setup. When i tried to execute the scripts manually changing my Custom Action project to Console Application from Class Library everything goes fine but when i tried to do the same through setup its gave me the following error.

    "There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run."

    Below is Log Trace i got.

    Note: 1: 1723 2: VerifyConnection 3: VerifyConnection 4: C:UsersadityakAppDataLocalTempMSIC429.tmp

    Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor.  Action VerifyConnection, entry: VerifyConnection, library: C:UsersadityakAppDataLocalTempMSIC429.tmp

    MSI (c) (68:B4) [09:57:20:611]: Product: CRMnext — Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor.  Action VerifyConnection, entry: VerifyConnection, library: C:UsersadityakAppDataLocalTempMSIC429.tmp

    Action ended 9:57:20: VerifyConnection. Return value 3.

    DEBUG: Error 2896:  Executing action VerifyConnection failed.

    The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2896. The arguments are: VerifyConnection, ,

    Any help??????

Skip to main content