Gadziu
Gadziu

Reputation: 687

Error 429 activex component can't create object while using self create reference

I created some add-in for excel in C#. In it is one public class for using in VBA. On my machine all works ok. When I install add-in on tester computer (I'm using InstallShield 2015 Limited Edition for Visual Studio to create setup file) I can't set object.

C# code

using System;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace PMTAddin
{
    [Guid("B2350EC1-522E-4B75-BB02-86BB0FD1A60E")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class PublicClass
    {
        public void test()
        {
            System.Windows.Forms.MessageBox.Show(
                        "test."
                    , "test"
                    , System.Windows.Forms.MessageBoxButtons.OK
                    , System.Windows.Forms.MessageBoxIcon.Error
                );
        }

        private int GetWorksheetID(Excel.Workbook wb, string worksheetName)
        {
            int result = 0;


            foreach (Excel.Worksheet ws in wb.Worksheets)
            {
                if (ws.Name == worksheetName)
                {
                    result = ws.Index;
                    break;
                }

            }

            return result;
        }

        [ComRegisterFunctionAttribute]
        public static void RegisterFunction(Type type)
        {
            Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable"));
            RegistryKey key = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true);
            key.SetValue("", System.Environment.SystemDirectory + @"\mscoree.dll", RegistryValueKind.String);
        }

        [ComUnregisterFunctionAttribute]
        public static void UnregisterFunction(Type type)
        {
            Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false);
        }

        private static string GetSubKeyName(Type type, string subKeyName)
        {
            System.Text.StringBuilder s = new System.Text.StringBuilder();
            s.Append(@"CLSID\{");
            s.Append(type.GUID.ToString().ToUpper());
            s.Append(@"}\");
            s.Append(subKeyName);
            return s.ToString();
        }
    }
}

In VBA project I checked reference to it on the list. It calls PMT.

VBA

Sub dsf()
    Dim o As PMT.PublicClass
    Set o = New PMT.PublicClass 'at this lane on other computer I got error 429. On my computer all work smoothly and method test is running.

    o.test
End Sub

I thought that maybe it was something .NET Framework, but it is installed. Any ideas?

EDIT:

I create two diffrent version for bittnes, but the same error.

But I found some new info. In registry on my computer it looks like this Registry on dev machine

and on tester machine it looks like this Registry on test machine

There are no CodeBase value... Do you think this is the problem? If it is, how I need to modify RegisterFunction method to correct this?

Upvotes: 1

Views: 4421

Answers (1)

Gadziu
Gadziu

Reputation: 687

After long seeking I found the solution. It's kind of partial, because for 64 bit Excel we need to register library manually (maybe someone knows, how to add bat file to installation file).

I found the answer on this site.

While creating Install Shield instalation file we need to do two things.

  1. Add .tlb file to application files (this step was done by me, before posting on stackoverflow)
  2. Click right on project.Primary output file and choose properities like in screenshot (for *.tlb file we need to check the same, but without "COM Interop") enter image description here

Without this the installer will not properlly register add-in in registry.

Install file created like this would register add-in for 32-bit excel only. If you want to use it also in 64-bit Excel you need to register library manually. I created simple bat file like this:

c:
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
regasm.exe "[pathToDLL]\AddInName.dll" /tlb:"[pathToDLL]\AddInName.tlb" /codebase 
pause

Remember, that you need to run it with admin rights.

Upvotes: 1

Related Questions