Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - [VB.NET] Come accedere alle risorse incorporate con CodeDOM ?
Forum - C# / VB.NET - [VB.NET] Come accedere alle risorse incorporate con CodeDOM ?

Avatar
alexandro1999 (Normal User)
Newbie


Messaggi: 2
Iscritto: 14/07/2014

Segnala al moderatore
Postato alle 18:52
Lunedì, 14/07/2014
Ciao a tutti, sto creando un programma in grado di generare un altro programma .exe tramite la compilazione di un file 'Test.Vb' contenente il codice sorgente che viene elaborato da un'istanza del CodeDOM Compiler.
Il mio attuale problema sono le risorse , ossia sono riuscito ad integrarne una nell'assembly che viene generato dal CodeDOM  ma ogni tentativo di leggerla ed assegnarla al BackgroundImage del Form (si tratta di un'immagine .JPEG) fallisce.

Per farvi capire meglio, vi posto le parti principali del codice che ora provo a spiegarvi, e vi dico che 'xp.JPEG' è l'immagine .JPEG che voglio integrare nell'assembly di output, mentre 'Form1.Resources' è il file .resources che contiene questa immagine ed è stato ottenuto utilizzando la funzione ResourceWriter :

Codice sorgente - presumibilmente C# / VB.NET

  1. 'Assegno il file di Input che deve essere compilato dal CodeDOM tramite la funzione CompileExecutable
  2. Success = CompileExecutable(Application.StartupPath & "\Test.Vb")
  3. 'Assegno la destinazione dell'immagine che dovrà essere scritta nell'assembly di output
  4. Dim byteStream As New FileStream(Application.StartupPath & "\xp.JPEG", FileMode.Open)



Codice sorgente - presumibilmente C# / VB.NET

  1. 'Inizio la creazione della risorsa Form1.resources ...
  2. Using rw As New ResourceWriter(".\form1.resources")
  3. '... che andrà a contenere la mia immagine xp.JPEG
  4.  rw.AddResource("\xp.JPEG", byteStream)
  5. ' Finalizza la creazione della risorsa e la chiude
  6. End Using



Successivamente ho aggiunto nelle opzioni del compilatore (System.Codedom.Compiler.CompilerParameters) il seguente codice per incorporare la risorsa form1.resources appena creata (e contenente la mia immagine xp.JPEG) nell'assembly di output :
Codice sorgente - presumibilmente Plain Text

  1. cp.EmbeddedResources.Add(Application.StartupPath & "\form1.resources")



Ora fin qua nessun problema , il mio file di output 'Debug_Test.exe' è aumentato di dimensione e posso concludere di aver incorporato correttamente la risorsa form1.resources.
Okey..e ora come la leggo???

Sto utilizzando il seguente codice che non mi restituisce errore ma ogni speranza di vedere apparire questa dannata immagine sul retro del mio form è vana.
Ho combattuto contro un 'ManifestResourceMissing exception' che da quanto ho capito significava che il nome della risorsa non era corretto e quindi il mio programma non riusciva a trovarla.
Quindi cosa sto sbagliando ?
Il codice che uso nel mio Test.Vb file per leggere la risorsa è :

Codice sorgente - presumibilmente VB.NET

  1. 'ottiene la risorsa form1.resources dall'assembly corrente
  2. Dim MyResources As New System.Resources.ResourceManager("form1", My.Application.GetType().Assembly)
  3.  
  4. Try
  5. 'ottengo l'immagine xp.JPEG dal MyResources (che adesso contiene appunto il mio file form1.resources)
  6. Me.BackgroundImage = DirectCast(MyResources.GetObject("xp.JPEG"), System.Drawing.Bitmap)
  7. Catch ex as exception
  8. MessageBox.Show(ex.Message)
  9. end try
  10. End Sub



La cosa strana è che non ricevo nemmeno un messaggio di errore ma st'immagine non si carica nel form.
Sto sbagliando procedura o c'è qualche errore nel codice?

A mio parere la causa può essere o il fatto che non ho assegnato nessun namespace nel mio file Test.Vb e il MyResources.GetObject("miaimmagine.JPEG") si aspetta invece di leggerle da un namespace (es. MyResources.GetObject("mionamespace.miaimmagine.JPEG") - cosa che ho provato a fare ma che non posso sapere se funziona perchè ricevevo un errore che mi impediva la compilazione : 'Nessun Sub Main in Form1' , errore che non appare se non aggiungo il namespace - ) oppure la mancanza di un file .resx che dovrebbe contenere il mio resources.designer, quello insomma che troviamo su Visual Studio se andiamo a vedere nei file nascosti sotto a Resources.Resx (cosa che ritengo altamente improbabile dato che la lettura delle risorse avviene appunto tramite i file .resources che da quanto so sono gli unici file binari che possono essere letti dall'assembly).

Queste sono mie divagazioni dovute ad una scarsa conoscenza dell'argomento , anche perchè se lo conoscevo bene non sarei qua a fare domande, quindi può benissimo trattarsi di un errore nel codice o una sbagliata procedura che sto cercando di utilizzare per leggere sta risorsa.

Ringrazio chiunque abbia avuto voglia di leggere tutto e chiunque mi darà una risposta, sono bloccato da una settimana e mezza su questo dannato errore, sul precedente ManifestResourcesException e sul valore null restituito da un imagestream (almeno ora di errori non ne ho).

PM Quote
Avatar
GN (Member)
Guru


Messaggi: 770
Iscritto: 30/04/2011

Segnala al moderatore
Postato alle 20:51
Lunedì, 14/07/2014
Personalmente non ho idea di cosa ci sia di sbagliato però tempo fa avevo trovato questo articolo su CodeProject che descrive, se ho capito bene, la stessa cosa che stai cercando di fare e potrebbe esserti utile: http://www.codeproject.com/Articles/19288/SlideShowBuilder


PM Quote
Avatar
alexandro1999 (Normal User)
Newbie


Messaggi: 2
Iscritto: 14/07/2014

Segnala al moderatore
Postato alle 13:02
Domenica, 20/07/2014
Risolto !
Innanzitutto grazie per la risposta, ero a conoscenza di quel codice sorgente ma l'avevo scartato dopo due minuti essendo in C ; vedendo però che non avevo alternative ci ho sbattuto un po' la testa e da quel codice ho scoperto una cosa interessante : tutto il procedimento che trasformava le immagini in file .resources era completamente inutile per il mio scopo.
Da quanto ho capito il NameSpace Resources è un'implementazione di VB.NET (credo?) che permette di gestire più facilmente diverse risorse, ma non è indispensabile.
Di conseguenza, nel mio caso è bastato fare :

Codice sorgente - presumibilmente Plain Text

  1. Codice sorgente - presumibilmente Plain Text

    cp.EmbeddedResources.Add(Application.StartupPath & "\miaimmagine.JPEG")




e richiamarla direttamente nel programma compilato dal CodeDom tramite il codice :

Codice sorgente - presumibilmente Plain Text

  1. Codice sorgente - presumibilmente Plain Text

    Me.BackgroundImage = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("miaimmagine.JPEG")




Ovviamente si può ripetere questa linea di codice per ogni risorsa che si vuole richiamare nel programma generato.

Per diversi motivi ho poi cercato una soluzione alternativa a questo codice (che comunque funziona bene) ed ho utilizzato questa procedura alternativa (scrivo tutto qui in caso possa servire a qualcuno) :
1.Trasformare l'immagine in una stringa Base64 (una stringa piuttosto lunga,circa 50'000 caratteri per 40 Kb di immagine)
2.Nel programma che verrà generato inserire questa stringa in una textbox invisibile
3.Associare l'evento Me.BackgroundImage alla funzione che 'ritrasforma' la nostra stringa di 50'000 caratteri nell'immagine originale.
In questo modo ho evitato di richiamare il System.Reflection ed il relativo Imports , ed ho evitato di avere delle risorse collegate all'Assembly. E' una soluzione non certo professionale ma funziona.
Funziona solo per le immagini, ma forse con qualche modifica si può fare lo stesso con altre risorse , tipo da file binario generico a stringa e viceversa, ma non ne sono sicuro.
Qui il codice :

Codice sorgente - presumibilmente VB.NET

  1. 'da immagine a stringa
  2. Public Shared Function ImageToBase64String(ByVal image As Image, _
  3.                                                ByVal imageFormat As ImageFormat)
  4.  
  5.         Using memStream As New MemoryStream
  6.  
  7.             image.Save(memStream, imageFormat)
  8.  
  9.             Dim result As String = Convert.ToBase64String(memStream.ToArray())
  10.  
  11.             memStream.Close()
  12.  
  13.             Return result
  14.  
  15.         End Using
  16.  
  17.     End Function
  18.  
  19. 'da stringa a immagine
  20. Public Shared Function ImageFromBase64String(ByVal base64 As String)
  21.         Try
  22.             Using memStream As New MemoryStream(Convert.FromBase64String(base64))
  23.  
  24.                 Dim result As Image = Image.FromStream(memStream)
  25.  
  26.                 memStream.Close()
  27.  
  28.                 Return result
  29.  
  30.             End Using
  31.         Catch ex As Exception
  32.             MsgBox("Error while loading image")
  33.         End Try
  34.  
  35.     End Function
  36.  
  37. 'convertire un'immagine contenuta nelle risorse in stringa ed associarla ad una textbox
  38. TextBox2.Text = ImageToBase64String(My.Resources.miaimmagine, ImageFormat.Jpeg)
  39.  
  40. 'ritrasformare la stringa nella textbox nell'immagine originale e assegnarla ad una picturebox
  41. PictureBox1.Image = ImageFromBase64String(TextBox2.Text)



Grazie ancora per l'aiuto !!

PM Quote
Avatar
GN (Member)
Guru


Messaggi: 770
Iscritto: 30/04/2011

Segnala al moderatore
Postato alle 13:28
Domenica, 20/07/2014
Di nulla. Quando trovi esempi in C# (che è più usato di VB) quasi sicuramente puoi applicarli a progetti in VB perchè entrambi i linguaggi si basano sul Framework .NET e differiscono quasi solo per la sintassi; per comprendere il codice io all'inizio quando non conoscevo la sintassi del C# mi aiutavo con questo convertitore http://www.developerfusion.com/tools/convert/csharp-to-vb/


PM Quote