1. To create a custom action method to call through Wix, you’ll need to add a Custom Action project to your solution. Right click on your solution, and then select “C# Custom Action Project”. I’ve named my project “MyApp.CustomActions”.
2. When you add the project, it will automatically create a CustomActions class with a public static method decorated with the CustomAction attribute, which is exactly what you’ll need to call your method through Wix.
Below is a method that I created to encrypt a connection string in app.config. You’ll notice that I initially tried to get the installation path from the “INSTALLFOLDER” key passed to Session by Wix, but I ended up commenting that section out. This ultimately didn’t work given my requirement to run the method as Administrator.
3. Back in your Wix project, add a new wxs file. I’ve named mine “CustomAction.wxs”. Add the following Fragment node to your file. This will tell Wix which dll to look for and which method to call for your custom action.
There are a few key points to mention about this Fragment node. It includes two changes that make it possible to run the method with elevated privileges. The Impersonate attribute is added and set to “no”. This will ensure that our method runs under Local System and not the user who runs the Msi. Also, the Execute attribute is set to “commit”, which means that our custom action will run at the end of installation. This also means that you can’t access variables from Session in your custom action code, which is unfortunate. For more info on these attributes, check out the Custom Action page on Wix.
Also, notice how the SourceFile attribute is pointing to the MyApp.CustomActions.CA.dll. The “CA” is important here. Your custom actions project will produce two dlls, one normal and one appended with “CA.” You need to point to the CA one.
4. Finally, add a InstallExecuteSequence tag to your Product.wxs file.
This will point back to the fragment you created in step #3. I’ve set the After attribute to “InstallFiles”. This means that the script will run after the files are installed on the target machine. This makes sense for my task, since I need to update the app.config file that is deployed by the Msi. I initially had this value set to “InstallFinalize”, which made the most sense to me based on the Execute=’commit’. However, Visual Studio complained about that value when I built the project, saying that it needed a stage between InstallInitialize and InstallFinalize.
I was able to see the Msi install log (including the log messages I included in my custom action method) using this helpful command.