0

I have a resource file embedded within my VB.NET 2019 project that with a button click, I would like to copy to the desktop. I tried to do this with a private sub so I could reuse the function but I cannot get it to work. The files are binary files.

Private Sub CreateBinary(ByVal objResource As Object, ByVal FullPath As String)
    Dim WriteBinary As BinaryWriter
    Try
        WriteBinary = New BinaryWriter(FullPath)
        WriteBinary.Write(objResource)
        WriteBinary.Close()
    Catch
    End Try
End Sub

Which I want to then call from the following:

CreateBinary(My.Resources.user32, My.Computer.FileSystem.SpecialDirectories.Desktop)

I can't seem to find anything that works. I have a similar function with other resource files that are text files that uses StreamWriter. All this really confirms is my binary files are embedded properly as resource files since they are all in the same place in my project.

Lance U. Matthews
  • 15,725
  • 6
  • 48
  • 68
Mike
  • 33
  • 8
  • 1
    There is no overload of `Write()` that takes an `Object`; it needs to know the simple type you want written. Also, an empty `Catch` block like that is going to suppress any exceptions that might get thrown, which is not-so-desirable in release code, but really counter-productive when you're trying to get something working. – Lance U. Matthews Jun 03 '22 at 19:45
  • First parameter of this method should be Byte(), the way it gets embedded as a resource. You can put the visual back in Visual Basic by clicking the Show All Files button in the Solution Explorer window, now you can navigate to and open Resources.Designer.vb. You'll see the "user32" declaration. And helps you make the next step, it needs to be written by FileStream or, easier, File.WriteAllBytes(). Just in case, don't actually embed user32.dll, it is an OS resource that can't reliably be copied to another machine. – Hans Passant Jun 03 '22 at 20:58

2 Answers2

2

The first thing to check on is how the resource is defined in the appropriate resx file (for VB, I think it will be in "My Project"). It should look something like this:

<value>[path to source file];System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>

If so, then the resource class provided by the designer will give you back a byte array, which is trivial to write to a file:

System.IO.File.WriteAllBytes(filename, My.Resources.FileResource)

(where "FileResource" is the name of the resource)

Craig
  • 2,248
  • 1
  • 19
  • 23
  • That is the issue. It won't let me use WriteAllBytes because it is a binary file. I error out on file type. Maybe there is a problem with my code? – Mike Jun 06 '22 at 11:17
  • @Mike How is the resource declared in the resx file? If it's not working, maybe there's something unusual about how it's declared (i.e. not as a byte array). `WriteAllBytes` should work as long as the resource is a byte array. – Craig Jun 06 '22 at 12:23
1

Try the following

Imports System.IO

Module ResourceExtensions
    <Runtime.CompilerServices.Extension()>
    Public Sub FileSave(BytesToWrite() As Byte, FileName As String)

        If File.Exists(FileName) Then
            File.Delete(FileName)
        End If

        Dim FileStream As New FileStream(FileName, FileMode.OpenOrCreate)
        Dim BinaryWriter As New BinaryWriter(FileStream)

        BinaryWriter.Write(BytesToWrite)
        BinaryWriter.Close()
        FileStream.Close()

    End Sub
End Module

Let's say the file in resource is Customers.xlsx, here I extract to C:\ExcelFiles. The path must exists.

Public Class Form1
    Private Sub ExtractButton_Click(sender As Object, e As EventArgs) _
        Handles ExtractButton.Click

        Dim exportFileName = "C:\ExcelFiles\Customers.xlsx"
        My.Resources.Customers.FileSave(exportFileName)

    End Sub
End Class
Karen Payne
  • 4,341
  • 2
  • 14
  • 31