首页 新闻 会员 周边 捐助

采用c#编写Excel自定义函数无法加载

0
悬赏园豆:10 [已解决问题] 解决于 2013-01-10 20:37

平台Windows 7(X86),VS2010,Excel2010,采用C#编写的Excel自定义函数,函数经控制台程序测试正确。可是生成解决方案,在Excel加载项中加载时提示:“***.dll为无效的加载宏”

我是参照msdn的示例来做的,示例来源:http://code.msdn.microsoft.com/CSExcelAutomationAddIn-c46f6956/sourcecode?fileId=52672&pathId=1482315659

如果我直接在示例项目中把函数换为我自己的函数就能完成加载;

但是如果我自己新建一个C# library项目,然后按照示例编写自己的自定义函数,结果在Excel加载时就出现“***.dll为无效的加载宏”的错误。

希望能得到大家的帮助

Teen的主页 Teen | 初学一级 | 园豆:193
提问于:2013-01-03 14:33
< >
分享
最佳答案
1

看下你的注册表项是否正确。

收获园豆:10
Launcher | 高人七级 |园豆:45050 | 2013-01-04 09:30

怎么可以知道注册表是不是正确呢?

Teen | 园豆:193 (初学一级) | 2013-01-05 18:16

@Teen: 示例来源:http://code.msdn.microsoft.com/CSExcelAutomationAddIn-c46f6956/sourcecode?fileId=52672&pathId=1482315659

如果我直接在示例项目中把函数换为我自己的函数就能完成加载;

既然示例能够正确运行,那么你就应该在注册表中去找到和此示例实现的COM组件相关的注册表项,然后根据规律去注册表中一个一个的检查自己编写的COM是否有相同的注册表项。

Launcher | 园豆:45050 (高人七级) | 2013-01-06 09:10

@Launcher: 我对注册表好陌生,其实我都看不懂示例后面注册代码那部分。我只是原封不动地抄了示例的代码,仅把自定义函数改为我自己的函数。我在博客园中的一些资料也看到除了自定义函数部分的其他代码是不需要改动的,你看看是不是因为还有别的地方需要改动而我不知道的,好吗。

Teen | 园豆:193 (初学一级) | 2013-01-06 20:28

@Teen: 示例项目里有个 ReadMe.txt,你照着那个做,然后每一步你有什么不明白的地方你再提出来。

Launcher | 园豆:45050 (高人七级) | 2013-01-07 09:20

@Launcher: 重新做了一遍,竟然成功了,谢谢你的指点。不过我真觉得好像还是按照以前那样做的,很神奇。说说还存在的问题吧,我对类前面的代码

[Guid("7127696E-AB87-427a-BC85-AB3CBA301CF3")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]

以及自定义函数写完之后的代码

        [ComRegisterFunction]
        public static void RegisterFunction(Type type)
        {
            // Add the "Programmable" registry key under CLSID
            Registry.ClassesRoot.CreateSubKey(
                GetCLSIDSubKeyName(type, "Programmable"));

            // Register the full path to mscoree.dll which makes Excel happier.
            RegistryKey key = Registry.ClassesRoot.OpenSubKey(
                GetCLSIDSubKeyName(type, "InprocServer32"), true);
            key.SetValue("",
                System.Environment.SystemDirectory + @"\mscoree.dll",
                RegistryValueKind.String);
        }

        [ComUnregisterFunction]
        public static void UnregisterFunction(Type type)
        {
            // Remove the "Programmable" registry key under CLSID
            Registry.ClassesRoot.DeleteSubKey(
                GetCLSIDSubKeyName(type, "Programmable"), false);
        }

        private static string GetCLSIDSubKeyName(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();
        }


这两处的代码有什么作用呢,能简要科普一下么,如果比较难于解释,你可以给我指出个方向或者资料让我自己去看吗?

谢谢你了Launcher!

 

Teen | 园豆:193 (初学一级) | 2013-01-10 00:36

@Teen: RegisterFunction 和 UnregisterFunction 是注册和注销方法,这两个方法没有什么特别的地方,只是向注册表写入或删除指定的注册表项,当你在命令行使用 RegAsm 来注册你的组件的时候,它会使用这两个方法来向注册表写入或删除相关的注册表项。

注册表项是其它程序用来查找和实例化你的组件的标识信息。

Launcher | 园豆:45050 (高人七级) | 2013-01-10 09:16

@Launcher: 谢谢了,看来我得学学注册表知识了~

Teen | 园豆:193 (初学一级) | 2013-01-10 20:35
其他回答(2)
0

用VBA吧,然后保存加载宏就可以了

56180825 | 园豆:1749 (小虾三级) | 2013-01-03 15:57
0

你的注册表是不是不对啊?

妍珊 | 园豆:1169 (小虾三级) | 2013-01-04 15:36

怎么可以知道注册表是不是正确呢?

支持(0) 反对(0) Teen | 园豆:193 (初学一级) | 2013-01-05 18:16

@Teen: 上一位不是已经回答你了,就那样试着做就行

支持(0) 反对(0) 妍珊 | 园豆:1169 (小虾三级) | 2013-01-06 09:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册