Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 19
  1. #1

    GetEntryAssembly ritorna null...come evitarlo?

    Vi spiego il mio problema...

    Ho un'applicazione WPF che utilizza una libreria di terzi per svolgere una specifica operazione e tale libreria in uno dei suoi metodi esegue l'istruzione Assembly.GetEntryAssembly().

    Il mio problema è questo, se eseguo l'applicazione WPF in debug (lanciando un apposito exe .NET di prova) la libreria funziona correttamente e l'istruzione Assembly.GetEntryAssembly() ritorna il riferimento all'assembly dell'eseguibile, ma in produzione ho una situazione diversa che mi crea qualche problemino.

    In produzione l'applicazione WPF è integrata con un'applicazione VB6 ed i programmi vengono lanciati da un menu scritto in VB6 sfruttando l'InteropFormLibrary; in questa situazione la libreria va in eccezione perchè l'istruzione Assembly.GetEntryAssembly() ritorna "null" in quanto non riesce a trovare l'assembly associato all'eseguibile. Il mio problema è che non posso modificare il codice della libreria perchè non ho i sorgenti a disposizione ed ho individuato l'istruzione che genera l'eccezione decompilando la dll ed analizzando il metodo che andava in eccezione.

    A questo punto la mia domanda è: esiste qualche modo per far in modo che il metodo "GetEntryAssembly" non ritorni "null"? Posso assegnarlo o "eluderlo" in qualche modo?

    Vi rigrazio in anticipo per ogni informazione a riguardo.
    Luca >> http://www.pollosky.it

  2. #2
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    è un esperimento ma potrebbe funzionare
    se nella dll del componente (occhio qui siamo borderline rispetto a licenze, condizioni d'uso ecc.) riesci a cambiare le linee di codice msil relative a:
    codice:
    Assembly a = Assembly.GetEntryAssembly();
    cone
    codice:
    Assembly a = Assembly.LoadFrom("pathdelllawpf.exe");
    forse (sottolineo forse ) sei a cavallo.

    Ps. sono curioso di sapere se funziona

  3. #3
    Scusa ma non credo di aver ben capito...

    come ti dicevo il mio problema è che non posso mettere le mani al codice della libreria, altrimenti avrei inserito un controllo sull'istruzione.

    Tu dove intendevi fosse inserita la modifica che hai suggerito?
    Luca >> http://www.pollosky.it

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,465
    Originariamente inviato da LukeSky
    come ti dicevo il mio problema è che non posso mettere le mani al codice della libreria, altrimenti avrei inserito un controllo sull'istruzione.
    La funzione restituisce una informazione che coincide con la richiesta che viene fatta; se nel contesto in cui utilizzi la libreria questa funzione restituisce un valore nullo e non puoi intervenire sul codice, non penso che si possa risolvere il problema.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

  5. #5
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    credo che chi ha progettato la libreria avesse la necessita di accedere al programma chiamante attraverso reflection, per farlo senza conoscere a priori il nome che l'utilizzatore da al proprio assembly usa il metodo GetEntryAssembly convinto del fatto che l'applicazioe wpf in questione sia l'exe entry point del processo. e' un trick poiche lo scopo non coincide con la sinopsi del metodo percui andava documentato...
    Cosa è successo? è successo che l'entry point è un programma unmanaged percui non esiste reflection ed è per questo che il metodo ritorna null.
    MA lo scopo era (spero e presumo) recuperare l'assembly del programma wpf, e tu ora sai come si chiama l'assembly del programma wpf anzi hai addirittura l'exe.
    Per cio se solo avessi i sorgenti, potresti cambiare una semplice riga di codice e saresti apposto.

    Ma non tutto è perduto. Possiamo fare il roundtrip della tua libreria scusami ma credevo che fino a qui ci fossimo capiti prima

    ti scrivo una miniguida al volo poi se hai problemi posti di volta in volta.



    - copia il file della libreria in una cartella (pippo) dentro c: cosi è piu facile scrivere i percorsi.
    - apri prompt dei comandi di visualstudio. si trova in Start-Programmi-visualstudio-visualstudioTools è tipo il prompt del dos ma con tutti i comandi di vs che andremo ad usare pronti all'uso.
    - digita ildasm /out=c:\Pippo\nuova.il nome_file_della_libreria.dll
    - si è generato un file nuova.il dentro pippo. Aprilo
    - qui viene il bello dobbiamo cambiare ogni riga
    codice:
    IL_xxxx:  call       class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetEntryAssembly()
    con

    codice:
    IL_xxxx:  ldstr      "ConsoleApplication4.exe" //il percorso della wpf exe rispetto alla dll
    IL_xxxx(+5):  call       class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::LoadFrom(string)
    qui c'è la difficoltà se non hai mai avuto a che fare con linguaggi tipo assembler. IL_XXXX sono codici di etichetta e il valore non è sequenziale ma cambia in base a quanto è "grande" l'istruzione precedente. L'istruzione di caricamento della stringa è "grande 5" mettendola prima della chiamata del metodo (che cambia in LoadFrom come hai visto) comporta il fatto che devi sfasare tutte le etichette successive di 5. A complicare le cose c'è il fatto che il sistema di numerazione è esadecimale. Ti conviene usare una calcolatrice con il sistema esadecimale per non sbagliarti. questo internamente al metodo perche per fortuna le etichette si azzerano ad ogni metodo.

    - Fatto questo lavoro non devi far altro che riassemblare la dll sempre dalla console di vs con: ilasm c:\pippo\nuova.il /dll (cancella prima la precedente ma TIENI UNA COPIA!). Se non ci sono errori nelle modifiche precedenti avrai la dll modificata (nuova.dll) altrimenti riceverai un messaggio di ricostruzione fallita.

    - cambia il nome e prova questa libreria

    Per capire meglio il discorso delle etichette ti posto un esempio che ho fatto precedentemente per risponderti.
    PRIMA
    codice:
    .method private hidebysig static void  Main(string[] args) cil managed
      {
        .entrypoint
        // Code size       27 (0x1b)
        .maxstack  2
        .locals init (class [mscorlib]System.Reflection.Assembly V_0,
                 class [mscorlib]System.Reflection.Assembly V_1,
                 bool V_2)
        IL_0000:  nop
        IL_0001:  call       class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetEntryAssembly() //LA DEVO CAMBIARE!
        IL_0006:  stloc.0
        IL_0007:  ldstr      "ConsoleApplication4.exe"
        IL_000c:  call       class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::LoadFrom(string)
        IL_0011:  stloc.1
        IL_0012:  ldloc.0
        IL_0013:  ldloc.1
        IL_0014:  call       bool [mscorlib]System.Reflection.Assembly::op_Equality(class [mscorlib]System.Reflection.Assembly,
                                                                                    class [mscorlib]System.Reflection.Assembly)
        IL_0019:  stloc.2
        IL_001a:  ret
      } // end of method Program::Main
    DOPO
    codice:
    .method private hidebysig static void  Main(string[] args) cil managed
      {
        .entrypoint
        // Code size       32 (0x20)
        .maxstack  2
        .locals init (class [mscorlib]System.Reflection.Assembly V_0,
                 class [mscorlib]System.Reflection.Assembly V_1,
                 bool V_2)
        IL_0000:  nop
        IL_0001:  ldstr      "ConsoleApplication4.exe" //ho caricato la stringa l'istruzione mi fara sfasare tutte le etichette di 5 infatti...
        IL_0006:  call       class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::LoadFrom(string)
        IL_000b:  stloc.0
        IL_000c:  ldstr      "ConsoleApplication4.exe"
        IL_0011:  call       class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::LoadFrom(string)
        IL_0016:  stloc.1
        IL_0017:  ldloc.0
        IL_0018:  ldloc.1
        IL_0019:  call       bool [mscorlib]System.Reflection.Assembly::op_Equality(class [mscorlib]System.Reflection.Assembly,
                                                                                    class [mscorlib]System.Reflection.Assembly)
        IL_001e:  stloc.2
        IL_001f:  ret
      } // end of method Program::Main

  6. #6
    rsdpzed
    Prima di tutto ti ringrazio per la chiarezza e per l'attenzione...

    dunque, ho provato ad applicare la tua soluzione e sono riuscito a ricostruire la dll "modificata"; per il momento, per fare un test, ho semplicemente sostituito l'istruzione GetEntryAssembly con GetExecutingAssembly.

    Però non sono riuscito a testarla perchè mi è sopraggiunto un'altro problemino...questa libreria infatti non è costituita da un'unica dll ma ne referenzia altre e se io provo ad utilizzare la dll modificata il programma va sempre in eccezione stampando il messaggio:

    Could not load file or assembly '[NOMEDLL], Version=[VERSIONE], Culture=neutral, PublicKeyToken=39c9965e432b5b02' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)

    Qualche idea?

    Comunque ti dico che sto provando a contattare gli sviluppatori della libreria per farmi fare la modifica...vediamo un pò se fanno prima loro o io
    Luca >> http://www.pollosky.it

  7. #7
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    con ildasm invece di creare nuova.il crea nome_esatto_libreria.il, quando la ricompilerai con ilasm creerà la dll con il nome uguale alla precedente. (cancella la precedente prima di ricompilare con ilasm). Spero che vada...

    Forse funziona anche con GetExecutingAssembly cosi ti risparmieresti un sacco di lavoro per via del fatto che come GetEntryPoint non ha argomenti.

  8. #8
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    forse ho trovato e facendo una prova al volo su una libreria 3d a caso ho visto che l'assembly lo firma!

    ilasm nome.il /res:nome.res /dll

    nome.re lo crea ildasm insieme al .il

  9. #9
    ottimo, grazie per la dritta...ho il codice e l'ambiente di produzione in ufficio, lo proverò Lunedì e ti farò sapere se è ok, grazie!
    Luca >> http://www.pollosky.it

  10. #10
    Niente, ho provato ma ancora ho problemi con le reference...sembra che la dll "modificata" non riesca a trovare le dll referenziate.
    Luca >> http://www.pollosky.it

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.