If we want to invoke some C#(VB,C++) code in the installation package, we should add custom action.
Add custom action project. C# code sample:
namespace SetupAction { public static class CustomActions { [CustomAction] public static ActionResult EnumerateSqlServers(Session session) { ... return ActionResult.Success; } [CustomAction] public static ActionResult VerifySqlConnection(Session session) { ... return ActionResult.Success; } } }
Open the .cproj fie of custom action project, and edit it. Add code below, save and build it, will get a file named 'SetupAction.CA.dll', 'SetupAction' is the name of my custom action project. Installation will invoke the '.CA.dll'
<Import Project="$(WixCATargetsPath)" Condition=" '$(WixCATargetsPath)' != '' " /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.CA.targets" Condition=" '$(WixCATargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.CA.targets') " /> <Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixCATargetsImported)' != 'true' "> <Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" /> </Target>
In the WiX project, add the custom action project to References, and define <CustomAction>
<!--The custom action DLL itself.--> <Binary Id="WebAppCA" SourceFile="$(var.SetupAction.TargetDir)$(var.SetupAction.TargetName).CA.dll" /> <!--The custom action .--> <CustomAction Id="EnumerateSqlServers" BinaryKey="WebAppCA" DllEntry="EnumerateSqlServers" Execute="immediate" Return="check" /> <CustomAction Id="VerifySqlConnection" BinaryKey="WebAppCA" DllEntry="VerifySqlConnection" Execute="immediate" Return="check" />
Pay attention: If the code in custom action need administrator privilege, should use another way to deal with it. Add attribute Impersonate="no" and define the parameters pass to the custom action method. Samples as below:
<CustomAction Id="SetConfigFile" BinaryKey="WebAppCA" DllEntry="SetConfigFile" Execute="deferred" Return="check" Impersonate="no"/> <!--Define the parameters pass to CustomAction 'SetConfigFile'--> <CustomAction Id="SetCustomActionPropertyValues" Property="SetConfigFile" Value="DATABASE_SERVER=[DATABASE_SERVER]; DATABASE_USERNAME=[DATABASE_USERNAME]; DATABASE_PASSWORD=[DATABASE_PASSWORD];" />
Always throw error: "Could not load file or assembly '...' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded."
Add "CustomAction.config" file to Custom Action project, and include code as below.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> <supportedRuntime version="v2.0.50727"/> </startup> </configuration>