2009-07-10 33 views
10

Uno de mis usuarios tiene un problema al intentar abrir un archivo de Excel a través de mi aplicación C#.C# y Excel interop

Todo funciona bien cuando lo ejecuto desde mi máquina y funciona para otros usuarios. No soy un experto en interoperabilidad de Excel, así que espero que ustedes puedan ayudarme.

Así es cómo se ha configurado:

he añadido una referencia a mi aplicación a Microsoft.Office.Interop.Excel.dll, versión 10.0.4504.0 (que creo que es Excel 2002). En mi máquina He instalado Excel 2007. En mi código intento abrir una hoja de trabajo de esta manera:

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); 

que registra la versión usuarios como Excel 9.0 (que es de 2000). El error que obtiene el usuario es:

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) 

Parece que el libro de trabajo no se puede abrir. El archivo se confirmó que existía y estaba suelto en la PC del usuario en C :. Pensé que al usar el PIA no tendría que preocuparme por los problemas de la versión de Excel. Sé que hay otros usuarios que usan Excel 2000, y funciona en mi máquina de desarrollo.

¿Alguna idea? Tal vez mis llamadas para abrir el archivo de Excel deberían cambiarse? Lo desafortunado es que no puedo reproducirlo.

+0

favor ayuda wiht esto si u puede http://stackoverflow.com/questions/9962157/safely-disposing-of-an-object-using-c-sharp/ –

Respuesta

14

"pensé utilizando el PIA no tendría que preocuparse de Excel versión problemas. Sé que hay otros usuarios utilizando Excel 2000, y funciona en mi máquina dev ."

Casi cierto, pero no del todo.

Al desarrollar contra PIA for Excel 2002, su programa será compatible para todas las versiones de Excel 2002 (10.0) y posteriores. La máquina que falla, sin embargo, se ejecuta con Excel 2000 (9.0), que es una versión debajo de la versión que ha desarrollado en contra.

No hay un PIA respaldado oficialmente debajo de Excel 2002, por lo que si necesita que su programa se ejecute en Excel 2000 (9.0), entonces deberá crear su propio ensamblado de interoperabilidad personalizado. Puede usar TlbImp.exe para crear un ensamblado de interoperabilidad para Excel 9.0, como se explica en el artículo Achieving Backward Compatibility with .NET Interop: Excel as Case Study.

Si su conjunto tiene un nombre fuerte, entonces necesita crear un conjunto de interoperabilidad con un nombre seguro. Esto se puede hacer proporcionando el nombre de su archivo .pfx o .snk mediante el modificador/keyfile, como se demuestra en el artículo How to create a Primary Interop Assembly (PIA). Ese artículo también está haciendo uso del modificador/primary para crear un "ensamblado primario de interoperabilidad".Hacer el ensamblado de interoperabilidad primario no es realmente necesario en su caso, pero no duele. Lo que el artículo omite, sin embargo, es el uso del modificador/sysarray, que debe usar.

Sin embargo, hacer un ensamblado de interoperabilidad con un nombre seguro tiene algunas complejidades que considerar. Para obtener más información, lea Using TLBIMP.exe to create Strong Named Interop Assemblies. (Entre otras cosas, este artículo explica la necesidad del modificador/sysarray.)

En resumen, hacer un ensamblado de interoperabilidad personalizado es muy simple si su ensamblaje no tiene un nombre fuerte. Es más complicado si su ensamblaje tiene un nombre fuerte y, por lo tanto, necesita crear un ensamblado de interoperabilidad con un nombre fuerte. Pero espero que estos artículos te ayuden a avanzar.

- Mike

+0

No hay problema Jaspion. .. por cierto, si está utilizando .NET 4.0 ya no necesita crear ensambles de interoperabilidad. :-) Así que esta necesidad de esta solución es solo para .NET 3.5 y versiones posteriores. –

2

estoy usando Microsoft.Office.Interop.Excel.dll: Runtime versión: v1.1.4322 Versión: 12.0.0.0

podría intentar esto:

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]; 
    } 
} 
0

he llegado prefiera guardar archivos de Excel como hojas de cálculo XML y luego abrirlos con objetos System.Xml. XML Uso mucho para todo tipo de cosas, mientras que Interop es una especie de arte negro para mí. Puede que no sea lo suficientemente bueno para sus necesidades, pero si lo es, probablemente sea mucho más fácil que enredarse con las bibliotecas de Interop.

Cuestiones relacionadas