2015-06-21 92 views
1

當然的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; 

注意:程序工作正常,我在我的辦公室2013年安裝,但我的客戶端計算機上顯示此錯誤

+0

可能重複[HRESULT:0x80040154(REGDB \ _E \ _CLASSNOTREG))](http://stackoverflow.com/questions/3003719/hresult-0x80040154-regdb-e-classnotreg)和[如何解決COM異常類未註冊(從HRESULT異常:0x80040154(REGDB_E_CLASSNOTREG))?](http://stackoverflow.com/questions/1496214/how-to-solve-com-exception-class-not-registered-exception-from-hresult-0x80040 ) – cubrr

+0

在這種情況下我是否必須在客戶端使用Regsvr32.exe? –

+0

「該程序在我安裝了office 2013的終端正常工作,但是這個錯誤顯示在我的客戶端電腦上」。那麼,這非常簡單,您必須**在運行代碼的機器上安裝Powerpoint(與您的程序相同的位數:32位和64位)。這是沒有辦法的。 –

回答

4

如前所述,問題在於沒有在客戶機上安裝Powerpoint。

powerpoint對象在COM類型庫中實現,並在安裝Powerpoint時安裝並註冊。 COM和.NET是完全不同的技術。要使用.NET應用程序中的COM類型,不要直接使用COM類型,而要使用特殊的互操作.NET程序集。這個程序集不包含任何PPT功能,它只是一個包裝器,作爲.NET應用程序和COM類型之間的橋樑。互操作程序集爲您完成所有辛苦工作,並定義可用作其他.NET類的.NET類型(來自COM類型),例如powerpoint.Application

互操作程序集只是一個普通的.NET程序集。您可以將其引用爲其他.NET引用(Embed Interop Types = false)。在這種情況下,您需要使用應用程序分發interop DLL。如果您設置Embed Interop Types = true,則互操作程序集將被編譯並直接嵌入到您的應用程序程序集中。而且,只有真正使用的類型和函數才被嵌入。所以使用這個選項具有優化和單一組裝的優點。

但是,即使在嵌入時,互操作信息也只是一個真正的COM類型的包裝,它必須安裝在客戶端機器上。如果不是,你會得到錯誤。 看到更多細節在https://msdn.microsoft.com/en-us/library/xwzy44e4.aspx

你的選擇是強制客戶端安裝PPT或避免Microsoft.Office.Interop.PowerPoint並使用一些第三方的PPT庫,你可以用你的應用程序分發。

1

有趣的是如何在錯誤信息中最重要的信息可以深埋其非常困難看到。

Class not Registered 

這是你的錯誤。基本上,您嘗試創建的對象不存在,或者沒有正確安裝在您運行軟件的機器上。 powerpoint是否已安裝?

+0

在我的開發計算機上,是office 2013,但在客戶端計算機上沒有安裝任何辦公軟件,我認爲這完全是關於它的, –

+0

@amrosama當然你不能使用'Microsoft.Office.Interop',那麼如果沒有安裝Office,你需要使用一個外部庫。 – cubrr

+0

@cubrr然後在參考屬性中嵌入Interop Types = true有什麼意義 –

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組件被稱爲「互操作庫」。這是與類型庫的一對一匹配。最重要的是在這個問題的上下文中,它只包含聲明,它不包含可執行代碼。代碼保留在用非.NET語言編寫的COM組件中。像使用C++編寫的Office程序一樣。

編譯時需要interop程序集,編譯器使用它來知道COM組件實現了哪些類型,以便它可以正確地鍵入檢查您編寫的代碼並在出錯時告訴您。它在運行時需要也是,只要使用其中一種COM類型,它就由CLR加載。

說完就互操作程序集部署到執行程序中的機器是一種負擔。一點都不需要,因爲你經常需要一個「主互操作程序集」,這是另一個與解決.NET類型身份問題有關的神祕術語。我會在這裏跳過一個細節。 Office的PIA非常大。確定誰負責確保在機器上部署PIA通常非常模糊。由於程序失敗時沒有人照顧它,這是一個非常普遍的不幸事件。

,微軟.NET 4的解決的負擔,兩個COM接口類型被認爲是相同時,他們具有相同的[的Guid],即使它們來自不同的組件來了。這允許一個技巧,編譯器現在可以將互操作程序集中的類型聲明覆制到輸出程序集中。只有你實際使用的那些。解決部署問題和龐大的互操作庫問題。您不再需要PIA,也不必再部署互操作程序集。這就是「嵌入互操作類型」的意思。

長話短說,元數據不足以執行代碼。你確實必須在目標機器上安裝Office程序。當它不是時,得到這個確切的異常。