开发者

.NET make a copy of an embedded file resource to the local drive

i'm new to the realm to working with Files in .NET

I'm creating a WPF application in VB.NET with the 3.5 Framework. (If you provide an example in C#, that's perfectly fine.)

In my project I have a Template for an MS Access database. My desired behavior is that when the users clicks File-->New, they can create a new copy of this template, give it a filename, a开发者_开发问答nd save it to their local directory.

The database already has the tables and some starting data needed to interface with my application (a user-friendly data editor)

I'm thinking the approach is to include this "template.accdb" file as a resource in the project, and write it to a file somehow at runtime?

Any guidance will be very, very appreciated.

Thanks!


be sure to pass in the fully qualified namespace name to ResourceName

Public Function ExtractResourceToDisk(ByVal ResourceName As String, ByVal FileToExtractTo As String) As Boolean

    Dim s As System.IO.Stream = System.Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream(ResourceName)
    Dim ResourceFile As New System.IO.FileStream(FileToExtractTo, IO.FileMode.Create)

    Dim b(s.Length) As Byte

    s.Read(b, 0, s.Length)
    ResourceFile.Write(b, 0, b.Length - 1)
    ResourceFile.Flush()
    ResourceFile.Close()

    ResourceFile = Nothing
End Function


Well the "easiest" thing would be just to include it as an output file in your program installation so that it gets installed somewhere when your application does (perhaps in your application's directory or a subdirectory off of it). Then you can simply use a File.Copy when you need to create a new one of the template. I'm not advocating that this is the best solution, simply the least amount of work. You can read up on the File.Copy method here.


public static void WriteResourceToFile(Assembly assembly, Type scope, string resname, string path)
{
    Stream res = assembly.GetManifestResourceStream(scope, resname);
    using (FileStream file = new FileStream(path, FileMode.Create))
    {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = res.Read(buffer, 0, buffer.Length)) > 0)
        {
            file.Write(buffer, 0, bytesRead);
        }
    }   
}

Should do the trick. Where scope would be a namespace scope for the resource name which allows you to shorten the resource name, which is fully qualified.


One I've answered before:

New Access database, how can it be done?

Interestingly that's a version hacked about from the original VB, but I don't have the VB to hand (long story).

I'd go a bit further, and suggest that you want to create your schema in code too - i.e. just dump out an empty database and then create the schema therein using DDL.

This C# and for SQL Server version - again I don't have the access/vb.net version to hand

How to create "embedded" SQL 2008 database file if it doesn't exist?


I modified Greg Bogumil answer from above to create an extension method. Now on any binary type resource file I can simply do something like this...

My.Resources.some_resource_file.ExtractResourceToDisk(newpath)

Note that you will have to add the below function to a module, you cannot create extension methods inside of a class.

''' <summary>
''' Extracts the binary resource file and saves it to the specified location.
''' </summary>
''' <param name="Resource">[Byte()] The binary resource file byte array.</param>
''' <param name="FileToExtractTo">[String] The full file path of the new file to be saved.</param>
''' <returns>[Boolean] Returns True on success.</returns>
<Extension>
Public Function ExtractResourceToDisk(ByVal Resource As Byte(), ByVal FileToExtractTo As String) As Boolean
    Try
        Using ms As New MemoryStream(Resource)
            Using ResourceFile As New FileStream(FileToExtractTo, FileMode.Create)
                Dim b(ms.Length) As Byte
                ms.Read(b, 0, ms.Length)
                ResourceFile.Write(b, 0, b.Length - 1)
                ResourceFile.Flush()
                ResourceFile.Close()
            End Using
        End Using
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function


First, make sure to set the Build Action of respective file set to Embedded resource.

Then based on @Greg Bogumil answer, you run this method:

public static bool ExtractResourceToDisk(string ResourceName, string FileToExtractTo) {
  //Choose any one assembly that matches your needs.
  var asm = System.Reflection.Assembly.GetEntryAssembly();
  //var asm = System.Reflection.Assembly.GetExecutingAssembly();
  //var asm = System.Reflection.Assembly.GetCallingAssembly();
  var s = asm.GetManifestResourceStream(ResourceName);
  var resFile = new System.IO.FileStream(FileToExtractTo, System.IO.FileMode.Create);
  if (resFile == null) return false;
  s.CopyTo(resFile);
  return true;
}

I use the CopyTo method instead because it's more concise.


I got this working with copying files to a destination directory from embedded file.

Dim FilePath As String = Application.StartupPath & "\testing.txt" 'file name and its extension
            Using MsiFile As New FileStream(FilePath , FileMode.Create)
                MsiFile.Write(My.Resources.testing, 0, My.Resources.testing.Length)
            End Using
            My.Computer.FileSystem.CopyFile(FilePath , "C:\destination", Microsoft.VisualBasic.FileIO.UIOption.AllDialogs, Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)
            MsgBox("done copy")
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜