2
votes

Sorry for a long question but I have to put as many details as I can to help you understand this issue better.

I'm using an msi installer created by InstallShield 2012, it runs properly on most computers but on some I get the generic 1001 error and upon clicking OK on that error everything rolled back. To troubleshoot, I ran the following code to generate the debug log from the installation

Setup.exe /v"/l*v \"C:\log.dat\""

enter image description here

The debug log shows error 2769 with a custom action xxxx.install did not close 1 MSIHANDLES.

While googling about this issue, I see a lot of people having this exact same error and most of the suggestions come down to check what your custom action is doing because it is the one that generates this error.

Here are what I've done to troubleshoot and isolate this problem so far:

  1. Open up the InstallShield project and look at the MSI deubbger, I noticed the custom action names in the log is part of the custom action InstallShield uses to install a Window Service as part of the installation.

enter image description here

  1. I look at how this service is installed, it turns out to be a C# executable that InstallShield invokes as a .NET Installer Class to install the service under the component's setting.

enter image description here

As per what is .NET installer class? you can look at the note below from InstallShield.

enter image description here

Fearing something is not right with my custom action code, i put in some debug logging and run the whole installation again, I still receive the same error but I do not see any exception being logged. The service actually created successfully and i can even run it as long as I don't click OK on the 1001 error which will trigger the roll back and uninstall this service.

    public ProjectInstaller()
    {
        try
        {
            using (StreamWriter w = File.AppendText("c:\\log.txt"))
            {
                Log("start installing", w);
            }

            InitializeComponent();

            using (StreamWriter w = File.AppendText("c:\\log.txt"))
            {
                Log("End Install", w);
            }

        }
        catch (Exception ex)
        {
            using (StreamWriter w = File.AppendText("c:\\log.txt"))
            {
                Log(ex.Message, w);
                Log(ex.StackTrace, w);
            }
        }
    }

    private void InitializeComponent()
    {
        this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
        this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();

        // 
        // serviceProcessInstaller1
        // 
        this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
        this.serviceProcessInstaller1.Password = null;
        this.serviceProcessInstaller1.Username = null;
        // 
        // serviceInstaller1
        // 
        this.serviceInstaller1.Description = "Healthcare Platform Service";
        this.serviceInstaller1.ServiceName = "psService";
        this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
        // 
        // ProjectInstaller
        // 
        this.Installers.AddRange(new System.Configuration.Install.Installer[] {
        this.serviceProcessInstaller1,
        this.serviceInstaller1});

    }

Based on my troubleshooting so far, I don't think the error is within the custom action code. However, that really leave me hanging because I don't really know what cause the custom action to fails; it looks like something did not close out the msi handles but this is really a black box to me.....

So any idea what this might be? How can I further delve down to figure out what the heck went wrong with this customer action _502E509F9B6F6675DFF9C310662BC1B5.install ?

Below are the custom actions sequence.

enter image description here enter image description here enter image description here enter image description here enter image description here

*EDIT: I found the link that talks about the similar error I have... however I verified my custom action doesn't have any parameter and that based on my verbose debug log I see all the path are properly resolved.

**EDIT: Add custom action sequence screenshots.

4
I've seen this error occur because the service name already exists.sgmoore
Not in my case, I verified the service is not there... i went as far as doing sc delete <servicename> just to check if there is any ghost service with the same name existsFylix

4 Answers

2
votes

The error is a generic one resulting from the infrastructure of installer classes not working. This is mostly a black box developed for Visual Studio setup projects. It uses a C++ Dll call to ManagedInstall which then loads a framework version, locates your assembly, instantiates your class with reflection and then calls the Install method. InstallUtilLib is architecture specific, and a mismatch between it and your managed code and the framework version will cause errors. If this happens only on one machine it might be this mismatch, or maybe that machine is broken in some way regarding that service.

That's just information that may help. However, if you have an actual InstallShield 2012 then you don't need installer classes at all. They were created for Visual Studio setups, and are not needed for practically every other MSI building tool that exists because they have built-in support for the MSI ServiceInstall and ServiceControl tables.

1
votes

To quote Jerry MaGuire... Stop, you had me at 1001. InstallUtil managed custom actions must be avoided at all cost. The first action is to eliminate the need for the custom action by using native windows installer capabilities. If the custom action is still needed the second action is to refactor using Windows Installer XML (Wix) Deployment Tools Foundation (DTF). Is a far better pattern for integrating managed code with MSI. It works very well with InstallShield.

IMO, InstallShield should have never made it so easy to wire up an InstallUtil custom action. They undoubtedly did so to satisfy customer requests and to ease migration to InstallShield but at the huge sacrifice of quality standards.

0
votes

I really need to see where this is sequenced. If this is deferred and before install initialize or after install finalize, that could be an issue.

0
votes

Hmm,

This is rather interesting... I found a Microsoft link that talks about the Event Source

By default, if I uninstall my software the event source will get removed as well. For some reason that is not the case I see, i think it isn't removed because the file to which EventMessageFile points to was being used/uninstall?

So reading the article above I went and remove out the registry manually found under Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MyProgramName

The installation no longer gives me 1001 error after I remove the above registry. It looks like InstallShield tries to install a window service but upon looking at this registry it deems the services already exists (even though it isn't).