错误 429 activex 组件在使用自创建引用时无法创建对象
Error 429 activex component can't create object while using self create reference
我在 C# 中为 excel 创建了一些 add-in。其中有一个publicclass供VBA使用。在我的机器上一切正常。当我在测试计算机上安装 add-in 时(我使用 InstallShield 2015 Limited Edition for Visual Studio 创建安装文件)我无法设置对象。
C#代码
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();
}
}
}
在 VBA 项目中,我在列表中检查了对它的引用。它调用 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
我认为可能是 .NET Framework 的问题,但它已安装。有什么想法吗?
编辑:
我为bittnes创建了两个不同的版本,但是同样的错误。
但是我发现了一些新信息。在我的计算机上的注册表中,它看起来像这样
在测试机器上看起来像这样
没有 CodeBase 值...您认为这是问题所在吗?如果是,我需要如何修改 RegisterFunction 方法来更正此问题?
经过长时间的寻找,我找到了解决方案。这有点偏,因为对于 64 位 Excel 我们需要手动注册库(也许有人知道,如何将 bat 文件添加到安装文件)。
我在这个 site 上找到了答案。
在创建 Install Shield 安装文件时,我们需要做两件事。
- 将 .tlb 文件添加到应用程序文件(这一步是我在 Whosebug 上发布之前完成的)
- 右击 project.Primary 输出文件并选择属性,如屏幕截图所示(对于 *.tlb 文件,我们需要检查相同的内容,但没有 "COM Interop")
否则安装程序将无法在注册表中正确注册加载项。
像这样创建的安装文件只会为 32 位 excel 注册加载项。如果你也想在 64 位 Excel 中使用它,你需要手动注册库。我创建了这样的简单 bat 文件:
c:
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
regasm.exe "[pathToDLL]\AddInName.dll" /tlb:"[pathToDLL]\AddInName.tlb" /codebase
pause
请记住,您需要 运行 它具有管理员权限。
我在 C# 中为 excel 创建了一些 add-in。其中有一个publicclass供VBA使用。在我的机器上一切正常。当我在测试计算机上安装 add-in 时(我使用 InstallShield 2015 Limited Edition for Visual Studio 创建安装文件)我无法设置对象。
C#代码
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();
}
}
}
在 VBA 项目中,我在列表中检查了对它的引用。它调用 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
我认为可能是 .NET Framework 的问题,但它已安装。有什么想法吗?
编辑:
我为bittnes创建了两个不同的版本,但是同样的错误。
但是我发现了一些新信息。在我的计算机上的注册表中,它看起来像这样
在测试机器上看起来像这样
没有 CodeBase 值...您认为这是问题所在吗?如果是,我需要如何修改 RegisterFunction 方法来更正此问题?
经过长时间的寻找,我找到了解决方案。这有点偏,因为对于 64 位 Excel 我们需要手动注册库(也许有人知道,如何将 bat 文件添加到安装文件)。
我在这个 site 上找到了答案。
在创建 Install Shield 安装文件时,我们需要做两件事。
- 将 .tlb 文件添加到应用程序文件(这一步是我在 Whosebug 上发布之前完成的)
- 右击 project.Primary 输出文件并选择属性,如屏幕截图所示(对于 *.tlb 文件,我们需要检查相同的内容,但没有 "COM Interop")
否则安装程序将无法在注册表中正确注册加载项。
像这样创建的安装文件只会为 32 位 excel 注册加载项。如果你也想在 64 位 Excel 中使用它,你需要手动注册库。我创建了这样的简单 bat 文件:
c:
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
regasm.exe "[pathToDLL]\AddInName.dll" /tlb:"[pathToDLL]\AddInName.tlb" /codebase
pause
请记住,您需要 运行 它具有管理员权限。