2014-05-13 9 views
5

Ho una DLL scritta in C# .NET che espone un'interfaccia COM, quindi un'applicazione vb6 può chiamare la mia DLL. Questa interfaccia è simile a:C# .net COM dll rompe il riferimento con l'applicazione vb6

[System.Runtime.InteropServices.Guid("3D2C106C-097F-4ED7-9E4F-CDBC6A43BDC4")] 
    public interface IZDPharmaManager { 
     [System.Runtime.InteropServices.DispId(2)] 
     SearchPatientEventArgs FoundPatient { get; set; } 
     [System.Runtime.InteropServices.DispId(3)] 
     IntPtr Start(string server, string database, string user, string password, bool integrated, int praktijkID, string userGUID, int userID, string userName, bool hasRightToSearchPatient); 
     [System.Runtime.InteropServices.DispId(4)] 
     void Stop(); 
     [System.Runtime.InteropServices.DispId(5)] 
     void InitializeSkinner(System.Object skinnerFramework); 
    } 

[System.Runtime.InteropServices.Guid("4438852E-CF2D-4DB0-8E6E-428F65A6B16C")] 
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
public interface IZDPharmaManagerEvents { 
    [DispId(1)] 
    void SearchPatient(ZDPharmaManager sender, SearchPatientEventArgs e); 
} 

    [System.Runtime.InteropServices.Guid("9297D43F-C581-3F0F-AA60-9506C6B77B5F")] 
    [ClassInterface(ClassInterfaceType.None)] 
    public class SearchPatientEventArgs : WebHIS.ZDPharmaceutisch.ISearchPatientEventArgs { 

     public SearchPatientEventArgs() { 
      //Nodig voor COM. 
     } 

     public int ID { get; set; } 
     public string FullName { get; set; } 
     public string OwnName { get; set; } 
     public string PartnerName { get; set; } 
     public string DateOfBirth { get; set; } 
     public string ZipCode { get; set; } 
     public string HouseNumber { get; set; } 
     public string BSN { get; set; } 
    } 

    public delegate void SearchPatientEventHandler(ZDPharmaManager sender, SearchPatientEventArgs e); 

    [System.Runtime.InteropServices.Guid("465AC7EC-27EF-3D95-AAA6-29D01FCF15A1")] 
    [ClassInterface(ClassInterfaceType.None)] 
    [ComSourceInterfaces(typeof(IZDPharmaManagerEvents))] 
    public class ZDPharmaManager : WebHIS.ZDPharmaceutisch.IZDPharmaManager { 

     public event SearchPatientEventHandler SearchPatient = null; 

     public SearchPatientEventArgs FoundPatient { get; set; } 

     //private MainForm GraphicalInterface { get; set; } 
     private ChoosePatient GraphicalInterface { get; set; } 

     public ZDPharmaManager() { 
      //Nodig voor COM. 
     } 

     #region IZDPharmaManager Members 

     public IntPtr Start(string server, 
      string database, 
      string user, 
      string password, 
      bool integrated, 
      int praktijkID, 
      string userGUID, 
      int userID, 
      string userName, 
      bool hasRightToSearchPatient) { 

      //Zet connectiestring. 
      DAL.DAC.CnnInfo = new System.Data.SqlClient.SqlConnectionStringBuilder() { 
       DataSource = server, 
       InitialCatalog = database, 
       UserID = user, 
       Password = password, 
       IntegratedSecurity = integrated 
      }; 

      DAL.DAC.PracticeID = praktijkID; 
      DAL.DAC.UserGUID = userGUID; 
      DAL.DAC.UserID = userID; 
      DAL.DAC.UserName = userName; 
      DAL.DAC.HasRightToSearchPatient = hasRightToSearchPatient; 

      //Apotheek IDs ophalen en bewaren. 
      DAL.DAC.PharmacyIDs = DAL.PracticeDAO.GetPharmacyByPracticeID(praktijkID); 

      //Initialiseer grafische interface. 
      //this.GraphicalInterface = new MainForm(); 
      this.GraphicalInterface = new ChoosePatient(); 

      //Haal ongekoppelde afhaalberichten op. 
      this.GraphicalInterface.Patients = new VML.PatientsVM(this); 

      //Toon grafische interface. 
      this.GraphicalInterface.Show(); 

      return this.GraphicalInterface.Handle; 

     } 

     public void Stop() { 
      foreach (var item in this.SearchPatient.GetInvocationList()) { 
       this.SearchPatient -= (SearchPatientEventHandler)item; 

      } 
      this.GraphicalInterface.Close(); 
      this.GraphicalInterface = null; 
      this.FoundPatient = null; 
     } 

     public void InitializeSkinner(System.Object skinnerFramework) { 

      WebHIS.ZDPharmaceutisch.SkinnerModule.SkinFramework = (XtremeSkinFramework.SkinFramework)skinnerFramework; 

     } 
     #endregion 

     internal virtual void OnSearchPatient(SearchPatientEventArgs e) { 
      if (this.SearchPatient != null) { 
       this.SearchPatient(this, e); 
      } 
     } 


    } 

Questo funziona correttamente. Ma ogni volta che costruisco questa DLL senza modificare l'interfaccia (perché ho dovuto risolvere qualcosa da qualche parte nella logica) il riferimento con l'applicazione vb6 è rotto e abbiamo bisogno di ricompilare l'applicazione vb6.

Qualcuno sa cosa sto facendo male? Perché avevamo DLL vb.net che non interrompevano il riferimento dopo la ricompilazione a causa di GUID fissi. Qualsiasi aiuto sarebbe molto apprezzato.

Aggiornamento Sia l'app vb6 sia la DLL sono operative. Ma quando ricompilare la DLL e testarla sul nostro server di test tramite l'applicazione vb6 ottengo un errore di automazione (che in genere significa che il riferimento è interrotto ed è necessario ricompilare anche l'app vb6)

+0

Non sono sicuro di cosa intendi, ma se hai collegato i riferimenti e ora stai apportando delle modifiche alla tua DLL, devi almeno chiudere il VB6 oi riferimenti liberi alla tua DLL dopo ogni compilazione della tua DLL. –

+0

Non è proprio quello che intendo. Sia l'app vb6 che la DLL sono operative. Ma quando ricompilare la DLL e testarla sul nostro server di test tramite l'applicazione vb6 ottengo un errore di automazione (che in genere significa che il riferimento è interrotto ed è necessario ricompilare anche l'app vb6) –

+0

Altre classi pubbliche nella DLL potrebbero essere automatiche UUID/GUID che cambiano quando si ricompila. Sembra che stia accadendo in un esempio che ho visto di recente. – DaveInCaz

risposta

11

Non vedo alcun forte conduce che potrebbe spiegare questo problema. L'attributo [Guid] per l'assembly è importante, che imposta l'ID della libreria dei tipi. E la [AssemblyVersion] conta, che imposta il numero di versione della libreria dei tipi. Gli attributi sono dichiarati nel file AssemblyInfo.cs del progetto. Assicurati che il tuo sistema di compilazione non scimmi con questi attributi.

Il modo migliore per scoprirlo è scoprire cosa cambia esattamente. Eseguire l'utilità OleView.exe dal prompt dei comandi di Visual Studio. File + Visualizza Typelib e seleziona il file .tlb. Copia/incolla il contenuto del pannello di destra in un file di testo.

Ricostruisci il progetto e ripeti l'esercizio OleView. Ora puoi semplicemente utilizzare uno strumento diffing per vedere cosa è esattamente cambiato. Aggiorna la tua domanda con quello che hai scoperto se hai bisogno di più aiuto.

+0

Grazie mille per avermi spiegato OleView.exe. Con questa utility sono stato in grado di scoprire che l'assembly ha esposto più di quanto sapessi e stava generando GUID (che interrompe i riferimenti del corso) –

+0

@DannyvanderKraan puoi fornire ulteriori dettagli su ciò che è stato esposto in modo imprevisto? Grazie – DaveInCaz

+0

@DaveInCaz Ci dispiace, ma ho chiesto questo quasi 3 anni fa, non riesco a ricordare. Il nocciolo della questione era che mentre pensavo che la build non stesse cambiando l'API del mio assembly, in realtà lo era. E ho scoperto usando il metodo descritto sopra. –