2009-08-31 70 views
3

有沒有一種方法可以以編程方式檢索C#使用的Excel Interop庫的版本?以編程方式檢索Excel庫的版本

我知道我大概可以在註冊表中找出安裝的Microsoft Office實例,但我很好奇,如果Excel庫包含此信息。

我知道這些信息包含在Visual Studio中,當您引用該庫時,但在運行時無法看到該信息。

我在問這個,因爲它在您保存工作簿時指定文件擴展名,並且如果您使用'.xls'保存2007工作簿,2007年會抱怨擴展名不正確。

回答

7

簡短的回答是這樣的:你不需要知道哪個版本PIA加載解決您的問題。你想知道哪個版本的Excel實際上正在運行。雖然運行的Excel版本和PIA版本是通常是相同的,但它們不一定是,在這種情況下,它是您關心的Excel版本,而不是PIA版本。

確定運行哪個Excel版本並不困難,但它不像應該那樣容易,因爲Excel.Application.Version屬性可以返回字符串,例如「11.0」或「9.0a」等,因此不一定直接將其解析爲一個整數值。你可以依靠的事實,一切小數點(「」)的左邊是版本號,然而,下面的代碼適用於所有版本:

Excel.Application excelApp = new Excel.Application(); 

string versionName = excelApp.Version; 
int length = versionName.IndexOf('.'); 
versionName = versionName.Substring(0, length); 

// int.parse needs to be done using US Culture. 
int versionNumber = int.Parse(versionName, CultureInfo.GetCultureInfo("en-US")); 

if (versionNumber >= 12) 
{ 
    // Excel 2007 or above. 
} 
else 
{ 
    // Excel 2003 or below. 
} 

對於PIA與Excel的對象模型問題,您的程序集在開發時參考的主Interop程序集(PIA)與實際在目標機器上運行時加載的PIA可能會有所不同。例如,如果您引用Excel 2002 PIA並且目標機器正在使用Excel 2007,那麼(通常)將會加載Excel 2007 PIA。規則是在目標機器上可用的最高版本的Office PIA在運行時被加載。

它變得更加複雜,因爲它可能(儘管絕對不可能)目標機器具有,例如,Excel 2007加載到目標機器上,但最高可用PIA適用於Excel 2003.在這種情況下,Excel 2007將加載,但是您的代碼將與Excel 2003 PIA一起工作。反過來也可能發生:Excel 2007 PIA可用,但機器上安裝的最高實際版本是Excel 2003--在這種情況下,Excel 2003將加載,但您的代碼將與Excel 2007 PIA一起工作。

這些場景在標準設置中不太可能發生。它最有可能發生在開發人員的機器上,其中(1)同時在機器上存在多個Excel版本,或者(2)Excel版本已被添加和刪除,但PIA不會隨其刪除(這本身也不太可能,因爲我相信這些PIA是自動卸載的,但我可能會錯誤地認爲這是錯誤的)。

更多相關信息,請參閱安德魯白教堂的文章Why is VS development not supported with multiple versions of Office?

雖然所有這些情況聽起來有點嚇人,在Excel中的對象模型的接口是非常一致的,因此幾乎是100%的向後兼容。一般來說,如果你綁定到一個給定的Excel PIA版本,那麼你的代碼將成功地運行在Excel或更高版本的Excel上,幾乎與所涉及的情景無關。正如您已經發現的那樣,有一些怪癖,但關鍵是要知道哪個Excel版本實際上正在運行。知道哪個PIA運行並不重要 - 只要您開發的PIA版本(或更高版本)可用,那麼PIA本身不應引起任何問題。

編輯:跟進到PHSR的評論:

當我保存工作簿我 產生,我需要知道什麼PIA我 是反對的工作,因爲這將是 保存在該格式。如果我得到PIA的 版本,我可以給 文件名以正確的擴展名(「xls」 vs「xlsx」)。即使保存爲「xls」的2007年工作簿爲 ,也會給 發出警告,指出與文件擴展名指定的格式不同 。 我想用 使用正確的擴展名隱藏該警告。你的 點是正確的,因爲它真的 最後並不重要(文件 仍然會打開),但在一些 實例(如這個)它確實。

我知道它可能「感覺」它是PIA是問題,但它是Excel對象模型,實際上在這裏負載重要,而不是PIA。此外,Excel應用程序版本號與PIA版本相同的可能性爲99.9%。他們會有所不同,這是非常罕見的。而且他們的區別在於,Excel版本很重要,而不是PIA(只要PIA與您開發的PIA版本相同或更高)。

爲了澄清這一點,PIA僅指定了涉及的接口,而不是功能。 Excel 2003 SaveAs methodExcel 2007 SaveAs method具有完全相同的參數簽名,所以PIA在這裏沒有區別。但是,如何執行SaveAs方法取決於哪個版本的Excel對象模型實際上正在運行

解決您的問題,我可以建議採取行動的兩種可能的課程之一:

(1)請我上面給來確定正在運行的Excel版本的代碼。如果你這樣做,並相應地調整你的代碼,它會起作用,我保證。如果失敗,請顯示您的代碼,我相信我們可以將其運行。

(2)不要在工作簿名稱中指定擴展名。讓Excel應用程序爲您添加默認擴展名。如果在Excel 2007中保存時指定了「.xls」擴展名,則說明您正確,它將遵守該擴展名,但不包括工作簿版本。然而,最簡單的方法是在保存工作簿時省略擴展名,Excel應用程序將自動追加「.xls」或「。XLSX」到工作簿的名稱,具體取決於Excel版本正在運行:

Excel.Application excelApp = new Excel.Application();  
Excel.Workbook workbook = excelApp.Workbooks.Add(Type.Missing); 

workbook.SaveAs(
    "MyWorkbook", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
    Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, 
    Type.Missing, Type.Missing); 

上述結果是一個名爲無論是工作簿‘MyWorkbook.xls’或‘MyWorkbook.xlsx’,具體取決於哪個版本的運行Excel總之,讓Excel爲你做的工作,讓你不必擔心它

+0

當我保存我生成的工作簿時,我確實需要知道我正在使用哪個PIA,因爲它將以該格式保存。如果我獲得PIA的版本,我可以將文件名改爲正確的擴展名(「xls」與「xlsx」)。即使2007年的工作簿保存爲「xls」,它也會提供與文件擴展名指定格式不同的警告。我想通過使用正確的擴展名隱藏該警告。你的觀點是正確的,因爲它最終並不重要(文件仍然會打開),但在某些情況下(如這個)它確實沒有關係。 – 2009-08-31 13:52:32

+0

確實是運行的Excel版本,您需要擔心這裏,而不是PIA版本,誠實。我承諾。在「編輯:跟進phsr的評論」部分的下方查看我的更新。 – 2009-08-31 14:25:47

2

我認爲windows註冊表在這方面是一個很好的信息來源。 確定相關的鍵並在運行時獲取它們的值。

此代碼可能是令人振奮:

Getting the office version

+0

我知道我可以從註冊表得到它,但我一直在尋找另一個辦法。示例代碼+1,謝謝。 – 2009-08-31 12:16:39

0

試試這個(從ExcelDna源代碼):

將此代碼放在一個類的地方聲明:

[DllImport("XLCALL32.DLL")] 
public static extern int XLCallVer(); 

調用此功能,你需要:

int version = XLCallVer()/256; 

或者,如果你使用ExcelDna您可以撥打直供:

double version = ExcelDnaUtil.ExcelVersion;