Wixsharp Debug Custom Action in Console

WIxsharp debug custom action in console

Not quite sure what was causing the problem, I deleted my bin folder and then ran a build and it now seems to be working. System.Diagnostics.Debugger.Launch() does work correctly it needs to be contained within an #if DEBUG as @Stein Åsmul stated. Once built in DEBUG run the outputed .msi, you will be prompted to open an instance of visual studio when you hit your custom action during install.

   [CustomAction]
public static ActionResult CustomAction(Session session)
{

#if DEBUG
System.Diagnostics.Debugger.Launch();
#endif
MessageBox.Show("Hello World!" + session[IISSessions.AppPoolName], "External Managed CA");

return ActionResult.Success;
}

How to check if it's a silent installation from the custom action DLL?

The UILevel property of Windows Installer will tell you whether the setup has been launched silently. Four different UI levels are possible:

  • INSTALLUILEVEL_NONE - 2 - switch: /qn - Completely silent installation.
  • INSTALLUILEVEL_BASIC - 3 - switch: /qb - Simple progress and error handling.
  • INSTALLUILEVEL_REDUCED - 4 - switch: /qr - Authored UI, wizard dialogs suppressed.
  • INSTALLUILEVEL_FULL - 5 - Authored UI with wizards, progress, errors (/qf).

UILevel may be better used to condition a whole custom action to run or not run depending on what the UILevel is set to? Or you can get its value inside the custom action and change behavior accordingly.

Essential Links:

  • Determining UI Level from a Custom Action.
  • Common problems with C++ Custom Actions
  • Debugging Custom Actions

Further Links:

  • How do I add C# methods to an existing large wix script
  • Debug C# custom actions
  • Determine if this is unattended installation mode?

UPDATE: From the old Wise Command Line Builder tool, here are some options for the MSI GUI. Note the use of plus and minus to show or hide completion screen for silent install:

Wise Command Line Builder

How to expose methods from a C# assembly which can be consumed as custom actions in Visual Studio Installer Projects (VS 2019)

Found the answer I was looking for in DllExport (https://github.com/3F/DllExport/wiki). This allowed me to create a .NET Framework assembly and export entry points to assembly methods as if they were conventional unmanaged C++ DLL exports, which can be invoked by msiexec as custom actions.

Basic steps:

  1. Create the assembly project and add a class with static methods to be exported.
  2. Add DllExport nuget reference to the project. The nuget includes a configuration tool; adding the nuget launches the tool. You need to identify your solution, the project within your solution, and (confusingly) the namespace containing the DllExport attribute (which should be System.Runtime.InteropServices). When you "Apply", it modifies the vcproj.
  3. Add the [DllExport] attribute to each static method to be exported. On build, an assembly will be created which has C++ entry points to the methods. NOTE by default, there will be an "AnyCPU" version of the assembly which does not contain any exports, in addition to x86 and x64 versions of the assembly which do. You need to use one of those.
  4. Add the x86 assembly to the installer project and reference the assembly and exported name in the custom action. You can also specify a value for CustomActionData.

Sample code:

using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;

namespace CustomActionFrameworkTest
{
public class CustomActions
{
/// <summary>
/// Import the MsiGetProperty method
/// </summary>
/// <param name="hInstall">Handle to the install instance</param>
/// <param name="szName">Property name we want the value of</param>
/// <param name="szValueBuf">Value</param>
/// <param name="pchValueBuf">Length of value (buffer size on input, actual length output)</param>
/// <returns></returns>
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern int MsiGetProperty(int hInstall, string szName,
[Out] StringBuilder szValueBuf, ref int pchValueBuf);

[DllExport]
public static int InstallTest(int handle)
{
// Debugger.Launch(); // If you need to debug

var sb = new StringBuilder(512); // Initialize to an arbitrary size
int size = 512; // Must give the function a buffer size

var status = MsiGetProperty(handle, "CustomActionData", sb, ref size);

if (status == 0)
{
var message = $"Got value '{sb}' from CustomActionData";

MessageBox.Show(message, "Test", 0);
}
else
{
MessageBox.Show($"MsiGetProperty failed with error code: {status}", "Error", 0);
}

return 0;// 0= success, 1602 = user exit, 1603 = failure
}
}
}

WIX execute custom action with admin privilege


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:

  • How to deploy settings files: Create folder and file on Current user profile, from Admin Profile
  • Handling write permission denied: System.UnauthorizedAccessException while running .exe under program files

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:

  • More on logging: Enable installation logs for MSI installer without any command line arguments


Related Topics



Leave a reply



Submit