MSI Installer cannot find InstallState when using custom action with parameters

KeithS picture KeithS · Feb 15, 2011 · Viewed 21.2k times · Source

First off, yes, I know that the VS Setup Projects are evil. It's what I have to work with. I've also seen several related questions, but they either go unanswered or they don't match my situation close enough for the answer to work (or they harp on about the evils of VS Setup Projects and the marvels of WiX).

I have an install project for my application. It worked just fine to copy files, but I needed to perform two custom actions after copying the files. I created an installer class and set it up as a custom action in the setup project, and the skeleton of it (which did no work, just showed a dialog so I could attach a debugger and look around) worked just fine. Then, I found I needed to pass parameters from the MSI to my custom action so I could access them via the Context property of the installer class.

Here's the current code of the installer class (some names have been changed to protect the innocent). It basically does nothing but show a dialog at the right time (after files are copied but before the installation is committed):

namespace MyApp.Install.CustomSetup
{
    [RunInstaller(true)]
    public partial class MyAppCustomInstallActions : System.Configuration.Install.Installer
    {
        public MyAppCustomInstallActions()
        {
            InitializeComponent();
        }

        protected override void OnAfterInstall(IDictionary savedState)
        {
            try
            {
                base.OnAfterInstall(savedState);
                if (MessageBox.Show(
                    "Custom Action OnAfterInstall successfully integrated. You can attach a debugger if desired. Do you wish to perform the custom actions?",
                    "DEBUG", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return;

                SetEditablePermissionOnFolder(savedState);
                SetApplicationSettingsFromWizard(savedState);
            }
            catch (Exception ex)
            {
                Context.LogMessage(ex.ToString());
                throw;
            }
        }

        private void SetApplicationSettingsFromWizard(IDictionary savedState)
        { 
            //TODO: Implement
        }

        private void SetEditablePermissionOnViewerFolder(IDictionary savedState)
        {
            //TODO: Implement
        }
    }
}

The plan is to get the custom actions working, then take out the dialog and just do it.

Here is the string for CustomActionData for the Install action of the setup project's custom actions:

/phonenumber=[phonenumber] /thirdpartyinstallpath1="[thirdpartyinstallpath1]\" /thirdpartyinstallpath2="[thirdpartyinstallpath2]\" /thirdpartyinstallpath3="[thirdpartyinstallpath3]\"

If I do not use this parameter string, it's fine but I have no parameters. If I do specify this string, the installer fails before my own dialog box shows up, with two errors: "Exception occurred while initializing the installation: Could not load file or assembly 'file:///C:\Windows\SysWOW64\Files' or one of its dependencies. The system cannot find the file specified", and "Error 1001. Could not find file C:\Program Files (x86)\MyCompany\MyApp\MyApp.Install.CustomSetup.InstallState".

What am I doing wrong? Am I doing anything wrong? Is there a solution that doesn't require me to re-create an installer using some different framework?

EDIT: I found that removing everything but the phone number parameter, and putting [PHONENUMBER] in quotes, allows that parameter to be passed. However, I cannot pass any of the directory paths; I tried with [INSTALLDIR] exactly how several blogs and walkthroughs say to do it, no dice.

Answer

bplus picture bplus · Oct 14, 2011

I had a similar problem and solved it by:

On the properties of your custom action set InstallerClass to false.