Stealth1234
Level 2

Managed Code Custom Action Failing

We are trying to use a managed code custom action using a default method signature to call a .dll file at the beginning of the UI sequence, but every time it runs it returns a value of 3, and provides no further information. Has anyone ever done this successfully?
Labels (1)
0 Kudos
2 Replies
Cary_R
Level 11

Sure, I've made this work. Sounds like something is not set up quite right is all.

My recommendations:

1. Add a Debugger.Launch() call at the start of the method. If it's not hit, it's likely an assembly load error.
2. Before taking further action, check to see if maybe you've got references that the *.dll needs as local reference (they aren't included automatically by InstallShield).
3. If you don't have a dependency issue, debug the assembly load log.
4. Sanity check: Make sure your method is declared as Public Static.
0 Kudos
Not applicable

I've gotten this to work in my Suite Managed Code CA sure it's the same in an MSI CA. I add the dll in the Support Files and add the following parameters for my custom action, I have multiple custom actions referencing different functions in my dll:

New Managed Code CA:
File: [SETUPSUPPORTDIR]InstallCheck.dll
Class: InstallCheck.PreInstallCheck
Method: SetDefaults

This is a small sample of how I'm using it:

[CODE]
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Data.SqlClient;
using System.Management;
using Microsoft.Win32;
using System.Windows.Forms;
using System.Diagnostics;
using System.ServiceProcess;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Data;
using Microsoft.Web.Administration;

namespace InstallCheck
{
[Guid("BAFAEAED-08C6-4679-B94E-487A4D89DE63")]
[TypeLibType(4288)]
public interface ISuiteExtension
{
[DispId(1)]
string get_Attribute(string bstrName);
[DispId(2)]
void LogInfo(string bstr);
[DispId(3)]
string get_Property(string bstrName);
[DispId(3)]
void set_Property(string bstrName, string bstrValue);
[DispId(4)]
string FormatProperty(string bstrValue);
[DispId(5)]
string ResolveString(string bstrStringId);
}

public class PreInstallCheck
{
const UInt32 ERROR_INSTALL_FAILURE = 1603;
const UInt32 ERROR_SUCCESS = 0;

ISuiteExtension GetExtensionFromDispatch(object pDispatch)
{
if (Marshal.IsComObject(pDispatch) == false)
throw new System.ContextMarshalException("Invalid dispatch object passed to CLR method");

return (ISuiteExtension)pDispatch;
}

public void SetDefaults(object pDispatch)
{
ISuiteExtension suiteExtension = GetExtensionFromDispatch(pDispatch);
try
{
string myProperty = suiteExtension.get_Property("AnyExistingProperty");
}
catch (Exception e)
{
}
}

// To have installer see the error
public UInt32 SetCheckBox(object pDispatch)
{
ISuiteExtension suiteExtension = GetExtensionFromDispatch(pDispatch);

string PROPERTY = suiteExtension.get_Property("PROPERTY");

if (PROPERTY = "good")
{
return ERROR_SUCCESS;
}
else
{
return ERROR_INSTALL_FAILURE;
}
}
}
}[/CODE]

Hope this helps.
0 Kudos