嵌入Interop类型问题

时间:2015-06-21 13:01:34

标签: c# .net visual-studio powerpoint

当然Embed interop类型功能很棒,但即使在简单的场景中我也无法使用它,所以请提供建议 这是我在没有安装powerPoint的机器上运行我的项目时得到的错误:

enter image description here

我的代码非常简单我只是从powerPoint创建对象,创建演示文稿并在其中滑动写入内容。

我嵌入的库是OfficeMicrosoft.Office.Interop.PowerPoint

将构建配置转换为x68并没有解决它,

我正在构建Windows应用程序并按下按钮单击代码,如下所示:

 private void button1_Click(object sender, EventArgs e)
 {
     var pp = new powerpoint.Application();
     var oPres=pp.Presentations;
     pp.Visible = Office.MsoTriState.msoTrue;
     powerpoint.Presentation  oPre= oPres.Add(Office.MsoTriState.msoTrue);

     powerpoint.Slides oSlides = oPre.Slides;
     powerpoint.Slide oSlide = oSlides.Add(1, powerpoint.PpSlideLayout.ppLayoutText);
     powerpoint.Shapes oShapes = oSlide.Shapes;
     powerpoint.Shape oShape = oShapes[1];
     powerpoint.TextFrame oTxtFrame = oShape.TextFrame;
     powerpoint.TextRange oTxtRange = oTxtFrame.TextRange;
     oTxtRange.Text = "All-In-One Code Framework";

     string fileName = Path.GetDirectoryName(
         Assembly.GetExecutingAssembly().Location) + "\\Sample1.pptx";
     oPre.SaveAs(fileName,
         powerpoint.PpSaveAsFileType.ppSaveAsOpenXMLPresentation,
         Office.MsoTriState.msoTriStateMixed);
     oPre.Close();

     pp.Quit();
     pp = null;
 }

在顶部我添加了

 using powerpoint = Microsoft.Office.Interop.PowerPoint; 
 using Office = Microsoft.Office.Core; 
 using System.IO; 
 using System.Reflection;

注意:程序在我安装Office 2013的时候工作正常,但是这个错误出现在我的客户端电脑上

3 个答案:

答案 0 :(得分:5)

如前所述,问题是客户端计算机上没有安装Powerpoint。

powerpoint对象在COM类型库中实现,并在安装Powerpoint时进行安装和注册。 COM和.NET是完全不同的技术。要从.NET应用程序中使用COM类型,您不能直接使用COM类型,而是使用特殊的互操作.NET程序集。这个程序集不包含任何PPT功能,它只是一个包装器,可以作为.NET应用程序和COM类型之间的桥梁。互操作程序集为您完成所有艰苦工作,并定义可用作其他.NET类的.NET类型(来自COM类型),例如 powerpoint.Application

互操作程序集只是一个普通的.NET程序集。您可以将其引用为其他.NET引用(Embed Interop Types = false)。在这种情况下,您需要与您的应用程序一起分发互操作DLL。如果设置Embed Interop Types = true,则会编译互操作程序集并将其直接嵌入到应用程序程序集中。而且,只嵌入了真正使用的类型和功能。因此,使用此选项具有优化和单组装的优势。

但是,即使嵌入式,互操作信息只是必须安装在客户端计算机上的真实COM类型的包装器。如果不是,则会收到错误消息。 请参阅https://msdn.microsoft.com/en-us/library/xwzy44e4.aspx

了解更多详情

您的选择是强制客户端安装PPT或避免使用Microsoft.Office.Interop.PowerPoint并使用您可以随应用程序分发的某些第三方PPT库。

答案 1 :(得分:1)

有趣的是,错误信息中最重要的信息可以被埋没得如此之深,以至于很难看到。

Class not Registered

这是你的错误。基本上,您尝试创建的对象不存在或者未在您运行软件的计算机上正确安装。 powerpoint肯定安装了吗?

答案 2 :(得分:1)

“嵌入互操作类型”意味着“嵌入Office程序”。您收到此错误的原因很简单,Powerpoint未安装在该计算机上。

我认为术语“互操作类型”可以使用解释。您可以使用COM自动化Office程序,COM是一种介于.NET之前的互操作技术,与.NET有许多相似之处。它还具有元数据的概念,就像.NET程序集一样,是编译器在添加对.NET程序集的引用时使用的类型信息。该元数据在COM中称为“类型库”。 Powerpoint的类型库是Office 2013版本的C:\ Program Files(x86)\ Microsoft Office \ Office15 \ MSPPT.OLB。

类型库并不完美,它们存在歧义问题,这些问题在用C ++编写的应用程序中并不重要,但在.NET中很重要。因此.NET设计者决定不直接使用类型库。并指定Tlbimp.exe utility,它将库内容转换为.NET程序集。可以直接由CLR和托管语言编译器使用,而无需处理解释类型库内容的麻烦。

按照惯例,由Tlbimp.exe生成的.NET程序集称为“互操作库”。它与类型库一对一匹配。最重要的是在这个问题的上下文中,它只包含声明,它不包含可执行代码。代码保留在COM组件中,以非.NET语言编写。就像用C ++编写的Office程序一样。

编译时需要互操作程序集,编译器使用它来了解COM组件实现的类型,以便它可以正确地键入 - 检查您编写的代码并告诉您何时出错。它在运行时也是 ,只要您使用其中一种COM类型,就会由CLR加载。

必须将interop程序集部署到执行程序的计算机上是一种负担。至少是因为你经常需要一个“主要互操作程序集”,这是另一个与解决.NET类型身份问题有关的神秘术语。细节我会跳过这里。办公室的PIA非常庞大。确切地说,谁负责确保PIA部署在机器上通常非常模糊。当没有人照顾它时程序失败,这是一个非常常见的事故。

Microsoft在.NET 4中解决的负担,两个COM接口类型在具有相同[Guid]时被认为是相同的,即使它们来自不同的程序集。这允许一个技巧,编译器现在可以将类型声明从interop程序集复制到输出程序集中。只有你实际使用的那些。解决部署问题和庞大的互操作库问题。您不再需要PIA,也不必再部署互操作程序集。这就是“嵌入互操作类型”的含义。

长话短说,元数据不足以执行代码。您确实必须在目标计算机上安装Office程序。如果不是,那就得到这个确切的例外。