C#和Excel互操作

我的一个用户在尝试通过我的C#应用​​程序打开一个Excel文件时遇到了问题。

当我从我的机器上运行它,一切工作正常,它适用于其他用户。 我不是Excel互操作专家,所以希望你们能帮助我。

这是如何设置的:

我添加了一个对我的应用程序的引用Microsoft.Office.Interop.Excel.dll,版本10.0.4504.0(我相信是Excel 2002)。 在我的机器上,我安装了Excel 2007.在我的代码中,我尝试打开一个工作表,如下所示:

using Microsoft.Office.Interop ... Microsoft.Office.Interop.Excel.ApplicationClass _excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass(); Microsoft.Office.Interop.Excel.Workbook excelWorkbook = _excelApp.Workbooks.Open(workbookPath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", false, false, 0, true, false, false); Microsoft.Office.Interop.Excel.Sheets excelSheets = excelWorkbook.Worksheets; Microsoft.Office.Interop.Excel.Worksheet excelWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)excelSheets.get_Item(1); 

我将用户版本logging为Excel 9.0(即2000)。 用户得到的错误是:

 Exception='System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad) 

看起来工作簿不能打开。 该文件被确认存在,并在C:用户的个人电脑上松动。 我想通过使用PIA,我不必担心Excel版本问题。 我知道还有其他用户使用Excel 2000,它可以在我的开发机器上运行。

有任何想法吗? 也许我的电话打开Excel文件应该改变? 不幸的是我无法复制它。

“我想通过使用PIA,我不必担心Excel的版本问题,我知道还有其他用户使用Excel 2000,它可以在我的开发机器上运行。

几乎是正确的,但不完全。

通过针对Excel 2002的PIA进行开发,您的程序将与所有版本的Excel 2002(10.0)及更高版本兼容。 但是,发生故障的计算机正在运行Excel 2000(9.0),该版本低于您开发的版本。

Excel 2002下面没有官方支持的PIA,所以如果你需要你的程序在Excel 2000(9.0)上运行,那么你将不得不创build自己的自定义互操作程序集。 您可以使用TlbImp.exe为Excel 9.0创build互操作程序集,如文章“ 实现.NET Interop的向后兼容性:Excel作为案例研究”中所述 。

如果你的程序集是强命名的,那么你需要创build一个强名称的互操作程序集。 这可以通过/ keyfile开关提供.pfx或.snk文件的名称来完成,如文章如何创build主互操作程序集(PIA)所示 。 那篇文章也是利用/ primary开关来创build一个“主互操作程序集”。 在你的情况下,制作互操作程序集并不是真的需要,但不会伤害。 然而,文章省略的是使用/ sysarray开关,您应该使用它。

然而,制作一个强名称的互操作程序集会有一些复杂性需要考虑。 有关更多详细信息,请阅读使用TLBIMP.exe创build强名称互操作程序集 。 (除此之外,这篇文章解释了/ sysarray开关的必要性。)

简而言之,如果你的程序集不是强命名的话,做一个自定义的互操作程序集是非常简单的。 如果你的程序集是强命名的,那么就更加复杂了,因此你需要创build一个强名称的interop程序集。 但希望这些文章应该让你去。

迈克

我正在使用Microsoft.Office.Interop.Excel.dll:运行时版本:v1.1.4322版本:12.0.0.0

可以试试这个:

  private object mMissingValue = System.Reflection.Missing.Value; private void CreateWorkbook(string fileName) { if (File.Exists(fileName)) { // Create the new excel application reference mExcelApplication = new Application(); // Open the file Workbook excel_workbook = mExcelApplication.Workbooks.Open(templatePath, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue, mMissingValue); Worksheet sheet = (Worksheet)mExcelWorkbook.Worksheets[1]; } } 

我宁愿将Excel文件保存为XML电子表格,然后用System.Xml对象打开它们。 XML我使用了很多种类的东西,而Interop对我来说是一种黑色艺术。 对于你的需求可能不够好,但如果是这样的话,可能比纠结Interop库要容易得多。