Sto creando un AddIn barra multifunzione VSTO per Excel, e sto memorizzando alcune informazioni sullo stato della cartella di lavoro nella mia applicazione che uso per aggiornare Pulsanti visivi abilitati. Considerando che possono esistere più cartelle di lavoro, sto memorizzando questo oggetto stato in un dizionario nella classe ThisAddIn. Il mio problema è che non so come ottenere un Hash/chiave/guida univoci per la cartella di lavoro perché tutto quello che ottengo è un wrapper COM che modifica continuamente l'hash. abbastanza giusto, lo capisco perfettamente.Ottieni Hashcode per cartella di lavoro Excel in VSTO per abilitare i pulsanti in base allo stato
Una soluzione che ho utilizzato per un lungo periodo di tempo è stata creare un guid e memorizzarlo in CustomDocumentProperties per la cartella di lavoro e mappare lo stato in base a tale chiave. Almeno funziona, ma fallisce se creo una copia della cartella di lavoro e la apro nella stessa istanza dell'applicazione e ho più cartelle di lavoro con lo stesso guid ora ..
Ho appena avuto un'idea ora che suppongo di poter aggiornare questo Guid sull'evento Workbook_Open. Ma ancora questa sembra una soluzione poco raccomandabile.
La seconda soluzione che ho trovato qui: http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/04efa74d-83bd-434d-ab07-36742fd8410e/
quindi ho usato che il codice ragazzi e ha creato questo:
public static class WorkbookExtensions
{
public static IntPtr GetHashery(this msExcel.Workbook workbook)
{
IntPtr punk = IntPtr.Zero;
try
{
punk = Marshal.GetIUnknownForObject(workbook);
return punk;
}
finally
{
//Release to decrease ref count
Marshal.Release(punk);
}
}
}
Funziona molto bene per qualche minuto, fino a quando non inizia a darmi l'infame errore "L'oggetto COM che è stato separato dal relativo RCW sottostante non può essere utilizzato" quando si accede ad Application.ActiveWorkbook.
È un modo sicuro di fare riferimento all'oggetto COM della cartella di lavoro? E se avessi due applicazioni nastro con questo metodo per ottenere un singolo GUID di cartelle di lavoro? Cosa succede se una di queste applicazioni esegue il garbage collector sul mio oggetto stato, che chiama un finalizzatore per chiamare Marshal.FinalReleaseComObject (cartella di lavoro)? Esiste un modo per ottenere il numero di riferi per una cartella di lavoro in modo da non chiamare FinalRelease prima che le altre app della barra multifunzione abbiano terminato con esse? Quali sono le migliori pratiche per la pulizia degli oggetti COM delle cartelle di lavoro in VSTO per continuare a giocare correttamente con queste altre app?
Sicuramente non sono la prima persona a voler attivare i pulsanti in base allo stato della cartella di lavoro, come fanno tutti gli altri? Ho esaminato alcuni altri articoli qui su Stack Overflow, ma nessuno mi ha aiutato con la soluzione Guida alle cartelle di lavoro.
Sto utilizzando la Ribbon Designer e mi sto collegando agli eventi Carica e disattiva della cartella di lavoro.
Grazie in anticipo, la speranza ha incluso tutti i dettagli.
** Oggetto COM che è stato separato dal suo R sottostante CW non può essere usato ** - sì io odio questo errore è un PITA, leggi questo: http://jake.ginnivan.net/vsto-com-interop –
Perché rilasci il puntatore IUnknown nella stessa funzione? Prova a tenerlo e rilasciarlo solo quando la cartella di lavoro è stata chiusa o qualcosa del genere. –
Brillante, grazie a @JeremyThompson! C'è molto da imparare da quell'articolo. Il VSTOContrib sembra essere perfetto per il mio prossimo progetto, ma non risolve i miei problemi immediati. @SimonMourier - Non sono molto esperto con il codice nativo, ma suppongo che se non rilasci il puntatore qui, perderò la traccia di esso per il rilascio successivo? – stuzor