Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态加载所有COM类型的Excel?_C#_Excel_Com_Interop - Fatal编程技术网

C# 动态加载所有COM类型的Excel?

C# 动态加载所有COM类型的Excel?,c#,excel,com,interop,C#,Excel,Com,Interop,我想探索动态使用Excel的途径。 我想在我的C#应用程序中使用Excel,而不包括DLL之类的东西。我会首先检查是否安装了所需的Excel版本并运行它 首先,我想得到我需要的所有类型,但我找不到: // works Type typeExcel = Type.GetTypeFromProgID("Excel.Application"); object excel = Activator.CreateInstance(typeExcel); object workbooks = typeExc

我想探索动态使用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库,我的应用程序将无法启动。如果我动态加载它们,我可以检查它们是否存在,并通知用户缺少的功能。

使用
dynamic

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

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

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

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

你正在寻找的治疗方法比问题严重得多。当您在代码段中尝试后期绑定Office代码时,它并没有什么特别之处。C#version 4中支持的动态关键字无疑使语法更加友好。然而,在编写代码时,它并没有任何友好之处,您将无法获得任何智能感知。而且在运行时没有什么友好的东西,您在编码时犯的错误将导致异常,并且后期绑定有相当大的开销

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

  • 请用户安装Office主互操作程序集(PIA)

  • 实际上很少需要PIA,只有当您在自己的公共方法中公开Office类型并在另一个程序集中使用它时,才需要PIA。在引用节点中选择Microsoft.Office.Interop程序集,并将其“复制本地”属性设置为true。重新生成,您将在生成目录中获取这些程序集。将它们与您自己的可执行文件一起复制到客户机

  • VS2010及以上版本提供了解决此部署细节的黄金解决方案。在引用节点中选择互操作程序集,并将“嵌入互操作类型”属性设置为True。互操作声明现在将合并到您自己的可执行文件中,您不再需要部署互操作程序集或PIA


由于您接受了VS2010及更高版本上提供的动态解决方案,最后一个项目就是您想要的。

您到底想实现什么?如果您希望依赖互操作(因此不必使用DLL,而是必须将给定的引用添加到您的项目中,并将您的开发目标定位到特定引用的Office版本),则不需要这样做。这里有一个入门指南:PS:还要记住,Office2003非常古老,有“一些特性”。例如,“可再发行的主互操作程序集”必须安装在要使用应用程序()的计算机上。Office 2007(其特定软件包)也需要这样做;但自从Office 2010以后就不再是了。@varocarbas我稍后会问我的老板我是否可以使用Office 2010。但现在我还是坚持2003年。这些是“经典”互操作规则。显然,GSerg提出了一些我不太确定的替代方案(与您的原始代码中所写的内容相符)。我已经编辑了您的标题。请看,“,其中的共识是“不,他们不应该”。究竟什么是动态的?它与互操作和不同的Office版本有什么关系?@varocabas
dynamic
是一个很好的例子。感谢您的澄清,非常有启发性。仍然不确定所有这些对Office/interop的确切适用性,但无论如何都很有趣。您能提供更多的代码来设置实际的单元格吗?缺少一些方法,如
工作簿。获取项目(…)
工作表。获取范围(…)
@mini-me。恐怕您还不明白您的请求:您请求的是上述互操作命名空间包含的内容;要访问它,您需要遵循我通过评论解释的步骤。动态(正如上面链接中完美解释的)与“对象”类似,也就是说,它对给定的内容(方法、属性等)一无所知。除此之外,我从未测试过这种方法,因此我甚至不确定它的实际可靠性和版本间兼容性。