3xodus Posted January 14, 2005 Posted January 14, 2005 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 ;) Quote Using: Visual Studio 2005/08 Languages: C#, Win32 C++, Java, PHP
IngisKahn Posted January 14, 2005 Posted January 14, 2005 Just create a FileStream and write the contents of the resource stream to it. Quote "Who is John Galt?"
3xodus Posted January 14, 2005 Author Posted January 14, 2005 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 :) Quote Using: Visual Studio 2005/08 Languages: C#, Win32 C++, Java, PHP
IngisKahn Posted January 15, 2005 Posted January 15, 2005 You dim a byte array to use as a buffer. Then read in from sw and write out to fstream. Quote "Who is John Galt?"
3xodus Posted January 15, 2005 Author Posted January 15, 2005 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 :) Quote Using: Visual Studio 2005/08 Languages: C#, Win32 C++, Java, PHP
IngisKahn Posted January 15, 2005 Posted January 15, 2005 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. Quote "Who is John Galt?"
3xodus Posted January 15, 2005 Author Posted January 15, 2005 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 Quote Using: Visual Studio 2005/08 Languages: C#, Win32 C++, Java, PHP
IngisKahn Posted January 15, 2005 Posted January 15, 2005 np glad I could help Quote "Who is John Galt?"
3xodus Posted January 29, 2005 Author Posted January 29, 2005 (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 January 29, 2005 by 3xodus Quote Using: Visual Studio 2005/08 Languages: C#, Win32 C++, Java, PHP
IngisKahn Posted January 29, 2005 Posted January 29, 2005 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. Quote "Who is John Galt?"
3xodus Posted January 29, 2005 Author Posted January 29, 2005 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 :) Quote Using: Visual Studio 2005/08 Languages: C#, Win32 C++, Java, PHP
IcingDeath Posted February 3, 2005 Posted February 3, 2005 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 Quote
kcwallace Posted December 7, 2005 Posted December 7, 2005 (RARLabs' date=' the makers of WinRAR have a RAR decompression control on their site)[/quote'] Can you provide a link for this control? Quote Go Beavs!!!
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.