Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    54
    Buona sera a tutti
    Riesumo questa discussione perchè sto letteralmente impazzendo...

    Ho una applicazione VB.NET 2005 "Server" che passa dei dati ad una applicazione Client.
    L'applicazione Client può essere un'applicazione VB ed ho bisogno quindi di creare un oggetto COM.
    Le strutture passate sulla rete tra le due applicazioni, devono essere (ovviamente) uguali e sono dichiarate in una classe che si chiama "Comuni".
    La classe Comuni utilizzata all'interno dell'applicazione VB.NET non può essere la stessa utilizzata dall'applicazione VB6...primo perchè mentre la "Comuni" di VB.net è una classe standard, la "Comuni" VB6, deve essere compilato come oggetto COM e secondo, perchè potrei avere la necessità in futuro che non tutto quello che viene passato all'applicazione .Net, venga passato anche all'applicazione VB6 (comunque al momento il codice all'interno, è identico).
    Mi trovo quindi con la "Comuni" utilizzata dalla parte Server VBNET che ha versione 2.6.0.0 e la "Comuni" VB6 che ha versione 1.0.2.2.

    Succede una cosa veramente strana (a mio avviso)...
    Una volta compilata la dll Comuni da utilizzarsi con VB6 e generato il file Tlb, entro nei riferimenti del progetto e mi carico il riferimento al file, poi, premo il "Play" per debuggare l'applicazione e, quando l'applicazione tenta di Deserializzare una struttura inviata dalla parte Server, mi viene generato l'errore "Impossibile trovare l'assembly 'Comuni, Version=2.6.0.0'...". Sembra quasi che la struttura passata via rete, contenga le informazioni di quale DLL l'ha serializzata (la dll server versione 2.6.0.0) e quando, VB6 tenta di deserializzarla con una DLL uguale, ma con versione diversa (la dll VB6 1.0.2.2), generi un errore.

    La cosa ancor più strana però è questa...
    Se io, invece di eseguire l'applicazione VB6 in debug, la compilo, copio la dll e il tlb all'interno della cartella del progetto e lancio l'exe...l'applicazione funziona correttamente
    Ovviamente, ho provato anche ad eseguire il VB6 in debug con la dll e il tlb nella directory del progetto ma non funziona comunque.

    Ho notato una cosa...siccome la DLL ha al suo interno delle funzioni che scrivono su di un file di log nella stessa routine dove si trova la DLL, ho notato che:
    -Quando lancio l'applicazione VB6 in debug, viene utilizzata la DLL presente nella cartella "Release" del progetto COM VBNET
    -Quando lancio l'exe dell'applicazione VB6, viene utilizzata la DLL copiata manualmente nella cartella del progetto (nonostante tra un tentativo e l'altro non venga eseguita alcuna registrazione con RegAsm o altro)

    A me, potrebbe anche andare bene che per provare l'applicazione debba compilare l'exe ogni volta ma purtroppo, ho la necessità di utilizzare la dll anche all'interno di un Database Access (con VBA). Con quest'ultimo, nonostante io esegua il "Compila" di VBA oppure crei il Database.accde (mde), va sempre ad utilizzare la DLL del progetto COM VB.NET e quindi non funziona.

    Qualche idea?
    Grazie infinite

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,477

    Moderazione

    Originariamente inviato da mmjc23
    Riesumo questa discussione perchè sto letteralmente impazzendo...
    Non riesumare discussioni ferme da tempo per affrontare un altro problema molto specifico, anche se strettamente correlato.

    Ho diviso la discussione.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    54

    Re: Moderazione

    Originariamente inviato da alka
    Non riesumare discussioni ferme da tempo per affrontare un altro problema molto specifico, anche se strettamente correlato.

    Ho diviso la discussione.

    Ciao!
    OK alka...

    Ho continuato a cercare Online ma non trovo nulla in merito a VB6
    Può darsi che in un progetto VB6 sia possibile dire al compilatore di ignorare la versione diversa della DLL? Tipo uno "SpecificVersion" o qualcosa del genere?

    Grazie

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    54
    EDIT [13/02/2012]:
    Ho provato ad installare la DLL nella GAC ma mi viene generato un errore in quanto la DLL, all'avvio, carica delle impostazioni dal file XML che cerca nello stesso percorso della DLL, ma ovviamente, non posso mettere il file XML nella C:\Windows\Assembly

    Aiutooooooo

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    54
    EDIT [13/02/2012] v2:

    Finalmente, dopo una settimana, sembra abbia risolto.
    Mi sa che...era proprio come pensavo...
    La DLL che serializza, probabilmente, scrive nel pacchetto inviato sulla rete la versione della DLL utilizzata (2.6.0.0); quando il pacchetto arriva all'applicazione Client, questa va in errore in quanto la DLL che lei utilizza è di una versione differente.

    Leggendo Online, sembrava che la soluzione fosse quella di impostare sia per l'oggetto che serializza che per quello che deserializza la proprietà "AssemblyFormat" al valore "Simple" in modo che venga ignorata la versione degli assembly.
    Nonostante questa impostazione (già comunque attiva di default), il problema rimaneva...

    Continuando le ricerche, ho trovato sul sito Microsoft che il Framework 2.0 SP2 e il 3.5 SP1 sembra avessero un baco che generava questo tipo di errore (vedi kb960442) ma nonostante abbia installato le relative patch (KB981574) il problema rimaneva...

    Ho trovato quindi su un sito c# un trucco per "imbrogliare" l'oggetto che effettua la deserializzazione in modo da sostiuire la versione dell'assembly all'interno del pacchetto ricevuto via rete con quello della DLL utilizzata prima di effettuare la deserializzazione.
    In questo modo, sembra funzionare correttamente...spero possa essere utile a qualcuno

    Codice per la deserializzazione [VB.NET]
    codice:
    Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    Dim ms As New IO.MemoryStream(Buffer)
    formatter.Binder = New mAPICommon.Functions.AllowAllAssemblyVersionDeserializationBinder
    Oggetto = formatter.Deserialize(ms)
    ms.Close()
    Codice Nuova classe che esegue l'"imbroglio" [VB.NET]
    codice:
    Public NotInheritable Class AllowAllAssemblyVersionDeserializationBinder
            Inherits System.Runtime.Serialization.SerializationBinder
    
            Public Overrides Function BindToType(ByVal assemblyName As String, ByVal TypeName As String) As System.Type
                Dim typeToDeserialize As Type
                Dim currentAssembly As String = System.Reflection.Assembly.GetExecutingAssembly().FullName
                assemblyName = currentAssembly
                typeToDeserialize = Type.GetType(String.Format("{0},{1}", typeName, assemblyName))
                Return typeToDeserialize
            End Function
    
    End Class
    Grazie e...alla prossima

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.