2009-07-10 19 views
10

Uno dei miei utenti sta riscontrando un problema durante il tentativo di aprire un file Excel tramite la mia app C#.C# ed Excel interop

Tutto funziona correttamente quando lo eseguo dalla mia macchina e funziona per altri utenti. Non sono un esperto di interoperabilità Excel quindi spero che voi ragazzi potete aiutarmi.

Ecco come è impostato:

ho aggiunto un riferimento alla mia app per Microsoft.Office.Interop.Excel.dll, versione 10.0.4504.0 (che credo sia Excel 2002). Sulla mia macchina ho installato Excel 2007. Nel mio codice provo ad aprire un foglio di lavoro in questo modo:

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

ho registrato la versione utenti come Excel 9.0 (che è 2000). L'errore che l'utente ottiene è:

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) 

Sembra che la cartella di lavoro non possa essere aperta. Il file è stato confermato per esistere ed era libero nel PC dell'utente in C :. Ho pensato di utilizzare il PIA non mi dovrei preoccupare dei problemi di versione di Excel. So che ci sono altri utenti che usano Excel 2000 e funziona sul mio computer di sviluppo.

Qualche idea? Forse le mie chiamate per aprire il file Excel dovrebbero essere cambiate? La cosa sfortunata è che non sono in grado di riprodurlo.

+0

si prega di aiuto con questo se u può http://stackoverflow.com/questions/9962157/safely-disposing-of-an-object-using-c-sharp/ –

risposta

14

"Ho pensato che utilizzando il PIA non avrei dovuto preoccuparsi di Excel versione problemi. So che ci sono altri utenti che utilizzano Excel 2000, e funziona sulla mia macchina dev ."

Quasi vero, ma non del tutto.

Sviluppandosi rispetto al PIA per Excel 2002, il programma sarà compatibile per tutte le versioni di Excel 2002 (10.0) e versioni successive. La macchina malfunzionante, tuttavia, è in esecuzione con Excel 2000 (9.0), che è una versione inferiore a, la versione sviluppata in precedenza.

Non esiste un PIA supportato ufficialmente sotto Excel 2002, quindi se è necessario eseguire il programma su Excel 2000 (9.0), sarà necessario creare il proprio assieme di interoperabilità personalizzato. È possibile utilizzare TlbImp.exe per creare un assembly di interoperabilità per Excel 9.0, come spiegato nell'articolo Achieving Backward Compatibility with .NET Interop: Excel as Case Study.

Se il proprio assieme ha un nome sicuro, è necessario creare un assembly di interoperabilità con nome sicuro. Questo può essere fatto fornendo il nome del file .pfx o .snk tramite l'opzione/keyfile, come dimostrato nell'articolo How to create a Primary Interop Assembly (PIA). Questo articolo utilizza anche l'opzione/primary per creare un "assembly di interoperabilità primario".Rendere l'assemblaggio dell'interoperabilità primario non è davvero necessario nel tuo caso, ma non fa male. Ciò che omette l'articolo, tuttavia, è l'uso dello switch/sysarray, che è necessario utilizzare.

La creazione di un assembly di interoperabilità con un nome sicuro presenta tuttavia alcune complessità da considerare. Per ulteriori dettagli, leggere Using TLBIMP.exe to create Strong Named Interop Assemblies. (Tra le altre cose, questo articolo spiega la necessità dello switch/sysarray.)

In breve, creare un assembly di interoperabilità personalizzato è molto semplice se l'assembly non ha un nome sicuro. È più complicato se l'assembly ha un nome sicuro e, pertanto, è necessario creare un assembly di interoperabilità con nome sicuro. Ma spero che questi articoli ti facciano andare.

- Mike

+0

Nessun problema Jaspion. .. btw, se si utilizza .NET 4.0 non è più necessario creare gli assembly di interoperabilità. :-) Quindi questa necessità di questa soluzione è solo per .NET 3.5 e seguenti. –

2

sto usando Microsoft.Office.Interop.Excel.dll: Runtime versione: v1.1.4322 Versione: 12.0.0.0

potrebbe provare questo:

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

Sono venuto preferire il salvataggio di file Excel come fogli di calcolo XML e quindi aprirli con oggetti System.Xml. XML Io uso molto per ogni genere di cose, mentre l'Interop è per me qualcosa di nero. Potrebbe non essere abbastanza buono per le tue esigenze, ma se lo è, probabilmente è molto più facile che aggrovigliare con le librerie di Interop.

Problemi correlati