【问题标题】:Loading all COM types of Excel dynamically?动态加载所有 COM 类型的 Excel?
【发布时间】:2013-10-02 02:53:47
【问题描述】:

我想探索这条动态使用 Excel 的路径。


我想在我的 C# 应用程序中使用 Excel,而不包括 dll 和其他东西。我会先检查是否安装了所需的 Excel 版本并运行它。

首先我想获得所有我需要的类型,但我无法获得它们:

// works
Type typeExcel = Type.GetTypeFromProgID("Excel.Application");
object excel = Activator.CreateInstance(typeExcel);
object workbooks = typeExcel.InvokeMember("Workbooks", BindingFlags.GetProperty, null, excel, null);

// this doesn't work, returns null
Type typeWorkbooks = Type.GetTypeFromProgID("Excel.Workbooks");

如果没有正确的类型,我将无法调用成员。那么我做错了什么?如何加载我需要的所有类型并知道它们在那里?我当前的 Excel 版本是 2003。


原因:如果我包含未安装在目标系统上的 COM 库,我的应用程序将无法启动。如果我动态加载它们,我可以检查它们的存在并通知用户缺少功能。

【问题讨论】:

  • 您到底想完成什么?如果您想依赖互操作(因此不必使用 DLL,但必须将给定的引用添加到您的项目并将您的开发定位到专门引用的 Office 版本),您不需要这样做。这里有一个入门指南:support.microsoft.com/kb/302084/en-us
  • PS:还请记住,Office 2003 相当老旧并且有“一些特殊性”。例如,“可再发行主互操作程序集”必须安装在您要使用该应用程序的计算机上 (microsoft.com/en-us/download/details.aspx?id=20923)。这也是 Office 2007(其特定软件包)所必需的;但自 Office 2010 以来不再存在。
  • @varocarbas 我稍后会问我的老板是否可以使用 Office 2010。但现在我坚持使用 2003。
  • 好的。这些是“经典”互操作规则。显然,GSerg 提出了一些我不太确定的替代方案(符合您原始代码中所写的内容)。
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。

标签: c# excel com interop


【解决方案1】:

使用dynamic

Type typeExcel = Type.GetTypeFromProgID("Excel.Application");

dynamic excel = Activator.CreateInstance(typeExcel);
excel.Visible = true;

dynamic workbooks = excel.Workbooks;
workbooks.Add();
workbooks.Add();

另见this answer

【讨论】:

  • 究竟什么是动态的?以及它与互操作和不同 Office 版本的关系是什么?
  • @varocarbas dynamicC# feature
  • 感谢您的澄清,非常有启发性。仍然不确定所有这些对 Office/interop 的确切适用性,但无论如何肯定很有趣。
  • 你能提供更多代码来设置一个实际的单元格吗?缺少一些方法,例如 workbook.get_Item(...)sheet.get_Range(...)
  • @mini-me 恐怕您还没有理解您的要求:您要求的是上述 Interop 命名空间包含的内容;要访问它,您需要按照我通过 cmets 解释的步骤进行操作。动态的(正如上面链接中完美解释的那样)就像“对象”,也就是说,它对给定的内容(方法、属性等)一无所知。最重要的是,我从未测试过这种方法,因此我什至不确定它的实际可靠性和版本间兼容性。
【解决方案2】:

如果我包含目标系统上未安装的 COM 库,我的应用程序将无法启动。

您正在寻找的治疗方法比问题严重得多。正如您在 sn-p 中尝试的那样,后期绑定的 Office 代码并没有什么好看的。 C# 版本 4 中支持的 dynamic 关键字无疑使语法更加友好。然而,在编写代码的时候,它并没有什么友好的地方,你不会得到任何 IntelliSense。并且在运行时没有什么友好的,你在编码时犯的错误会导致异常并且后期绑定有相当大的开销。

有一些简单的对策可以确保互操作程序集可用:

  • 要求您的用户安装 Office 主互操作程序集 (PIA)。

  • 真正需要 PIA 的情况很少见,只有当您在自己的公共方法中公开 Office 类型并在另一个程序集中使用它时才需要。在 Reference 节点中选择 Microsoft.Office.Interop 程序集并将其 Copy Local 属性设置为 true。重新构建,您将在构建目录中获得这些程序集。将它们与您自己的可执行文件一起复制到客户端计算机。

  • VS2010 及更高版本具有此部署细节的黄金解决方案。在 Reference 节点中选择互操作程序集并将 Embed Interop Types 属性设置为 True。互操作声明现在将合并到您自己的可执行文件中,您不必再部署互操作程序集或 PIA。

由于您接受了 dynamic 解决方案,在 VS2010 及更高版本中可用,最后一个项目符号就是您想要的。

【讨论】:

    猜你喜欢
    • 2012-02-28
    • 2021-10-24
    • 2013-01-27
    • 2010-12-06
    • 2018-09-04
    • 1970-01-01
    • 2017-05-18
    • 2014-05-21
    • 1970-01-01
    相关资源
    最近更新 更多