.NET делает копию встроенного файлового ресурса на локальный диск - PullRequest
1 голос
/ 08 апреля 2010

Я новичок в области работы с файлами в .NET

Я создаю приложение WPF в VB.NET с 3.5 Framework. (Если вы приведете пример на C #, это прекрасно.)

В моем проекте у меня есть шаблон для базы данных MS Access. Мое желаемое поведение заключается в том, что когда пользователи нажимают Файл -> Создать, они могут создать новую копию этого шаблона, присвоить ему имя файла и сохранить его в своем локальном каталоге.

База данных уже содержит таблицы и некоторые исходные данные, необходимые для взаимодействия с моим приложением (удобный редактор данных)

Я думаю, что подход состоит в том, чтобы включить этот файл "template.accdb" в качестве ресурса в проект и как-то записать его в файл во время выполнения?

Любое руководство будет очень, очень ценится.

Спасибо!

Ответы [ 6 ]

5 голосов
/ 08 апреля 2010

обязательно передайте полное имя пространства имен 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
2 голосов
/ 08 апреля 2010
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);
        }
    }   
}

Должен сделать свое дело.Где область действия - это область пространства имен для имени ресурса, которая позволяет сократить имя ресурса, которое полностью определено.

2 голосов
/ 08 апреля 2010

Что ж, «самой простой» вещью было бы просто включить его в качестве выходного файла в установку вашей программы, чтобы он устанавливался где-нибудь, когда это делает ваше приложение (возможно, в каталоге вашего приложения или вне его подкаталога). Затем вы можете просто использовать File.Copy, когда вам нужно создать новый шаблон. Я не защищаю, что это лучшее решение, просто наименьшее количество работы. Вы можете прочитать о методе File.Copy здесь .

1 голос
/ 08 апреля 2010

Тот, на кого я отвечал раньше:

Новая база данных Access, как это сделать?

Интересно, что версия взломана из оригинального VB, но у меня нет VB в руках (длинная история).

Я бы пошел немного дальше и предложил бы также создать свою схему в коде - т.е. просто выгрузить пустую базу данных, а затем создать схему в ней с помощью DDL.

Это C # и для версии SQL Server - опять же у меня нет версии access / vb.net под рукой

Как создать «встроенный» файл базы данных SQL 2008, если он не существует?

0 голосов
/ 28 июля 2017

Сначала убедитесь, что для Build Action соответствующего файла установлено значение Embedded resource.

Затем, основываясь на ответе @Greg Bogumil, вы запускаете этот метод:

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;
}

Вместо этого я использую метод CopyTo, потому что он более лаконичен.

0 голосов
/ 24 августа 2016

Я изменил ответ Грега Богумила сверху, чтобы создать метод расширения. Теперь для любого файла ресурсов двоичного типа я могу просто сделать что-то вроде этого ...

My.Resources.some_resource_file.ExtractResourceToDisk(newpath)

Обратите внимание, что вам нужно добавить указанную ниже функцию в модуль, вы не можете создавать методы расширения внутри класса.

''' <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
...