Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Using this thread by Plausibly Damp (http://www.xtremedotnettalk.com/showthread.php?t=83574), and various other threads, I've pretty much got the hang of how to use icons / images and such from resources. One thing I can't figure out is how to save the file - pretty much extracting the file from my apps resource, to the HD.

 

Is there a way to do this, without 'cheating' by setting the image in a picturebox and saving it from there... A method that can work on all filetypes maybe - I'm thinking it would be possible to make a (very basic) installer this way, by adding a compressed archive to the project, then extracting it to a temporary location, then decompressing it (RARLabs, the makers of WinRAR have a RAR decompression control on their site) and then deleting the compressed archive. Registry entries could also be made either in code from the 'installer', or by executing a .reg - I suppose you could make a fairly good installer with some work.

 

Sorry for the long-whinded explanation - and tia for any help ;)

Using: Visual Studio 2005/08

Languages: C#, Win32 C++, Java, PHP

Posted
Just create a FileStream and write the contents of the resource stream to it.

 

Hi - thanks for the advice. I've never used FileStream before, but from various forum posts, I've put this together -

       Dim ASM As [Assembly]
       Dim fStream As New FileStream(InputBox("Extract to (w/ .rar ext)", "Extract to *.rar"), FileMode.Create, FileAccess.Write)
       Dim sw As System.IO.FileStream
       ASM = [Assembly].GetExecutingAssembly()
       sw = ASM.GetManifestResourceStream("ResExtract.Test.rar")
       fStream.Write(array() as byte, offset as integer, count as integer) ' 
       sw.Close()

Am I going in the right direction here? If so, what is my "array as byte"? I don't really know much about this, so sorry if this is totally wrong or if I use the wrong terms :p - I think I have to convert the .rar resource so a byte array, and said byte array would be the array for fStream.Write() :-\

 

Also, I'm assuming for the offset, that would simply be 0, and for count, it would be the length of the byte array?

 

Again, sorry if I'm talking crap here, I'm only just starting to look into System.IO :)

Using: Visual Studio 2005/08

Languages: C#, Win32 C++, Java, PHP

Posted
You dim a byte array to use as a buffer. Then read in from sw and write out to fstream.

Thanks for that - I get how this should work, but I'm missing something. I used MSDN and this forum, but this is the best I have got so far:

       Dim myAssem As [Assembly]
       Dim fStream As New FileStream(Application.StartupPath & "extracted.zip", FileMode.Create, FileAccess.Write)
       Dim sw As System.IO.FileStream
       Dim bBuffer() As Byte 'buffer
       myAssem = [Assembly].GetExecutingAssembly()
       [u]sw = myAssem.GetManifestResourceStream("ResExtraction.Test.zip")[/u]
       sw.Read(bBuffer, 0, 100)   'read 100 bytes
       fStream.Write(bBuffer, 0, 100) 'write an array of 100 bytes

The line of code that I've underlined is throwing up the error "An unhandled exception of type 'System.NullReferenceException' occurred in ResExtraction.exe.

Additional information: Object reference not set to an instance of an object."

 

Any idea what I've done wrong here? Thanks for the help :)

Using: Visual Studio 2005/08

Languages: C#, Win32 C++, Java, PHP

Posted

2 things.

First, GetManifestResourceStream doesn't return a FileStream, it returns a Stream so you need to change your dim of sw (Another example of the benefits of Option Strict).

Second, you never create your byte buffer, throw an = new Byte(100) in there.

"Who is John Galt?"
Posted
2 things.

First, GetManifestResourceStream doesn't return a FileStream, it returns a Stream so you need to change your dim of sw (Another example of the benefits of Option Strict).

Second, you never create your byte buffer, throw an = new Byte(100) in there.

 

Thanks for all your help IngisKahn, it now works perfectly :) Though the biggest file I tested was 2MB, it seems really fast - though my code could be much better.

 

Anyway, thanks a lot for helping me with this :D

Using: Visual Studio 2005/08

Languages: C#, Win32 C++, Java, PHP

  • 2 weeks later...
Posted (edited)

Hi, sorry to bring this thread up again - but I have a problem somewhere :(

 

I was working on the routine - getting a progress bar and labels to follow the progress of the extraction etc... And though I've finally got that working properly, it takes *ages* to extract anything.

 

The file that is embedded into my test app is 315kb, and used to extract almost instantly. It now takes around a minute or more.

 

If anyone can spot what my problem is or offer any advice to speed it up, that'd be great.. Also I ought to mention that this routine is running in it's own thread (so my app isn't frozen during the extraction), I don't suppose that could cause a problem?

 

Thanks ! Here's the code - (Edit: I have had to use code ... /code tags, since VB tags put all of the code on one line, making the page unreadable :()

               Try
       Dim myAssem As [Assembly]
 Dim fStream As New FileStream(Application.StartupPath & "\nfo.rar", FileMode.Create, FileAccess.Write) 'InputBox("Dir to extract to", "Extract to-"), FileMode.Create, FileAccess.Write)
       Dim sw As System.IO.Stream
       Dim resSize As Long = 0 'The size of the resource
       Dim resDone As Long = 0 'Amount extracted
       myAssem = [Assembly].GetExecutingAssembly()
       sw = myAssem.GetManifestResourceStream("ResExtraction.Test.rar")
                    Dim bbuffer(sw.Length / 1024) As Byte 'Stream buffer
                    resSize = sw.Length
                    lblFilesize.Text = resSize
                    PB.Maximum = resSize
                    PB.Minimum = 0
                    PB.Step = PB.Maximum / sw.Length
                    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
                    Do
                        sw.Read(bbuffer, 0, 1)
                        fStream.Write(bbuffer, 0, 1)
                        'Update labels, progress bar etc... ***********************
                        resDone = resDone + 1
                        lblExtracted.Text = resDone
                        PB.PerformStep()
                        PB.Text = PB.Value & "%"
                        '/Updates ***************************************************
                    Loop Until PB.Value = PB.Maximum 'resDone = sw.Length
                    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
                    MsgBox("Extracted!", MsgBoxStyle.Information, "Extraction is complete")
                    cmdExtract.Enabled = True
                    Exit Sub
                Catch ex As Exception
                    MsgBox(ex.ToString, MsgBoxStyle.Critical, "ResExtraction Error")
                    Exit Sub
                End Try
    

Edited by 3xodus

Using: Visual Studio 2005/08

Languages: C#, Win32 C++, Java, PHP

Posted
I can't explain the sudden slow down, but going thru the file one byte at a time is generally very slow. Pick a buffer size (1024 is ok), open the file stream specifing that buffer size, and read and write that many bytes each time. Of course you have to test and handle the case when the number of bytes left is less than the buffer size.
"Who is John Galt?"
Posted
I can't explain the sudden slow down' date=' but going thru the file one byte at a time is generally very slow. Pick a buffer size (1024 is ok), open the file stream specifing that buffer size, and read and write that many bytes each time. Of course you have to test and handle the case when the number of bytes left is less than the buffer size.[/quote'] Thanks again for the replies IngisKahn :)

 

That's the reason I tried to make the buffer size based on the resource filesize (Dim bbuffer(sw.length / 1024)), but when I tried to read and write 1024 bits at a time, the resulting .rar file was around 97MB (although interestingly, when I extract it using WinRAR, it works fine and extracts to the normal filesize.. The 97MB file functioned just the same as the proper 315kB original file :s)

 

However thanks for the comment - I'll try to work out a better way to decide the biffer size, based on the resource filesize, and maybe the # of bytes read and written at a time should be based on that same formula?

 

Thanks again, I'll see what I can do with this :)

Using: Visual Studio 2005/08

Languages: C#, Win32 C++, Java, PHP

Posted

RAR files prolly look like this:

 

Start marker

Data

End Marker

 

 

Your RAR file prolly looks like this

 

Start marker

Data

End Marker

00000000000000 <- Its filed with 90 MB of zeros :P

  • 10 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...