Oppure

Loading
14/07/14 16:52
alexandro1999
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 :

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


'Inizio la creazione della risorsa Form1.resources ...
Using rw As New ResourceWriter(".\form1.resources")
'... che andrà a contenere la mia immagine xp.JPEG
 rw.AddResource("\xp.JPEG", byteStream)
' Finalizza la creazione della risorsa e la chiude
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 :
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 è :

'ottiene la risorsa form1.resources dall'assembly corrente
Dim MyResources As New System.Resources.ResourceManager("form1", My.Application.GetType().Assembly)

Try
'ottengo l'immagine xp.JPEG dal MyResources (che adesso contiene appunto il mio file form1.resources) 
Me.BackgroundImage = DirectCast(MyResources.GetObject("xp.JPEG"), System.Drawing.Bitmap)
Catch ex as exception
MessageBox.Show(ex.Message)
end try
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).
aaa
14/07/14 18:51
GN
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: codeproject.com/Articles/19288/…
aaa
20/07/14 11:02
alexandro1999
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 :

[CODE]cp.EmbeddedResources.Add(Application.StartupPath & "\miaimmagine.JPEG";)[/CODE]

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

[CODE]Me.BackgroundImage = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("miaimmagine.JPEG";)[/CODE]

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 :

'da immagine a stringa
Public Shared Function ImageToBase64String(ByVal image As Image, _
                                               ByVal imageFormat As ImageFormat)

        Using memStream As New MemoryStream

            image.Save(memStream, imageFormat)

            Dim result As String = Convert.ToBase64String(memStream.ToArray())

            memStream.Close()

            Return result

        End Using

    End Function

'da stringa a immagine
Public Shared Function ImageFromBase64String(ByVal base64 As String)
        Try
            Using memStream As New MemoryStream(Convert.FromBase64String(base64))

                Dim result As Image = Image.FromStream(memStream)

                memStream.Close()

                Return result

            End Using
        Catch ex As Exception
            MsgBox("Error while loading image")
        End Try

    End Function

'convertire un'immagine contenuta nelle risorse in stringa ed associarla ad una textbox
TextBox2.Text = ImageToBase64String(My.Resources.miaimmagine, ImageFormat.Jpeg)

'ritrasformare la stringa nella textbox nell'immagine originale e assegnarla ad una picturebox
PictureBox1.Image = ImageFromBase64String(TextBox2.Text)


Grazie ancora per l'aiuto !!
aaa
20/07/14 11:28
GN
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 developerfusion.com/tools/convert/csharp-to-vb/
aaa