【问题标题】:.NET make a copy of an embedded file resource to the local drive.NET 将嵌入的文件资源复制到本地驱动器
【发布时间】:2010-04-08 19:19:05
【问题描述】:

我刚接触 .NET 中的文件

我正在使用 3.5 框架在 VB.NET 中创建 WPF 应用程序。 (如果您提供 C# 中的示例,那很好。)

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

数据库已经有了与我的应用程序交互所需的表格和一些起始数据(用户友好的数据编辑器)

我在想的方法是将这个“template.accdb”文件作为资源包含在项目中,并在运行时以某种方式将其写入文件?

我们将非常非常感谢任何指导。

谢谢!

【问题讨论】:

    标签: .net wpf vb.net ms-access file-io


    【解决方案1】:

    确保将完全限定的命名空间名称传递给 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】:

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

      【讨论】:

        【解决方案3】:
        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 是资源名称的命名空间范围,它允许您缩短资源名称,这是完全限定的。

        【讨论】:

          【解决方案4】:

          我之前回答过的一个:

          New Access database, how can it be done?

          有趣的是,这是从原始 VB 窃取的版本,但我手头没有 VB(长话短说)。

          我会更进一步,并建议您也想在代码中创建架构 - 即只需转储一个空数据库,然后使用 DDL 在其中创建架构。

          这个 C# 和 SQL Server 版本 - 我手头没有 access/vb.net 版本

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

          【讨论】:

            【解决方案5】:

            我从上面修改了 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
            

            【讨论】:

              【解决方案6】:

              首先,确保将相应文件集的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 方法,因为它更简洁。

              【讨论】:

                【解决方案7】:

                我通过将文件从嵌入文件复制到目标目录来完成这项工作。

                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")
                

                【讨论】:

                  猜你喜欢
                  • 2023-01-24
                  • 2016-12-28
                  • 1970-01-01
                  • 2018-12-02
                  • 1970-01-01
                  • 2011-01-22
                  • 2021-12-21
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多