当然Embed interop
类型功能很棒,但即使在简单的场景中我也无法使用它,所以请提供建议
这是我在没有安装powerPoint的机器上运行我的项目时得到的错误:
我的代码非常简单我只是从powerPoint创建对象,创建演示文稿并在其中滑动写入内容。
我嵌入的库是Office
和Microsoft.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的时候工作正常,但是这个错误出现在我的客户端电脑上
答案 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程序。如果不是,那就得到这个确切的例外。