2010-04-08 66 views
1

我是新来的境界,在.NET中对文件进行处理.NET使嵌入文件资源的副本到本地驱动器

我创建与3.5框架在VB.NET WPF应用程序。 (如果你在C#中提供了一个例子,那很好。)

在我的项目中,我有一个用于MS Access数据库的模板。我希望的行为是,当用户单击文件 - >新建时,他们可以创建此模板的新副本,为其指定文件名,并将其保存到本地目录中。

数据库已经拥有的表,并与我的应用程序(一个用户友好的数据编辑器)

接口所​​需要的一些数据开始我想的办法是包括这个“template.accdb”文件作为资源在项目中,并在运行时以某种方式将其写入文件?

任何指导将非常非常感激。

谢谢!

回答

5

一定要在完全合格的命名空间名称传递给资源名称

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 
+0

美丽的解决方案!它在第一次尝试中工作。你们是如此聪明:p – 2010-04-08 23:58:09

2

那么“最简单”的事情就是将它作为输出文件包含在程序安装中,以便在应用程序执行时(可能位于应用程序目录或其子目录中)安装。然后,您可以在需要创建新模板时简单地使用File.Copy。我不主张这是最好的解决方案,只是最少的工作量。您可以阅读File.Copy方法here

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

应该这样做。其中scope是资源名称的命名空间范围,它允许您缩短资源名称,这是完全限定的。

0

我修改了Greg Bogumil从上面的答案来创建扩展方法。 现在任何二进制类型的资源文件,我可以简单的做这样的事情......

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 
0

首先,请务必将设置为Embedded resource相应文件的Build Action

然后根据@格雷格博古米尔答案,运行此方法:

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方法,而不是因为它更简洁。