上一篇文章中我们讲解了如何打包文件,这一篇我们讲解如何提取文件。
打包的主要思路:将所需要打包的文件的二进制写入Resx文件中,然后运用生成项目时可以把Resx文件作为嵌入的资源的特性,把打包文件隐藏在万博官网用户登录的Exe中,然后安装的时候在提取出来。
.NET提供了两个可以写Resx文件的类:ResXResourceReader和ResourceManager。我们可以看看其构造函数。
比较后,我们可以发现ResourceManager才是我们想要的。因为ResXResourceReader只能读取存在与磁盘上的Resx文件的信息,而我们的Resx文件时嵌入到Exe文件当中的,所以ResourceManager才是最适合我们的。
提取文件
我们可以使用ResourceManager(String, Assembly)构造函数来创建我们想要的ResourceManager,第一个参数为Resx文件对应的命名空间加类名,第二个参数为万博官网用户登录Exe所对应的Assembly。
下一步我们需要遍历资源文件中的节点,读取每个节点的二进制,然后写到磁盘上。但是纵观ResourceManager提供遍历Resx中所有节点的功能的。如下:
CreateFileBasedResourceManager(String, String, Type)
GetNeutralResourcesLanguage(Assembly)
GetObject(String)
GetObject(String, CultureInfo)
GetResourceFileName(CultureInfo)
GetResourceSet(CultureInfo, Boolean, Boolean)
GetSatelliteContractVersion(Assembly)
GetStream(String)
GetStream(String, CultureInfo)
GetString(String)
GetString(String, CultureInfo)
GetType()
InternalGetResourceSet(CultureInfo, Boolean, Boolean)
MemberwiseClone()
ReleaseAllResources()
那么我们怎么知道用户当初打包的时候到底打包了哪些文件呢。我们可以在打包文件的时候,也同时把所有的文件名都写入到某一个节点中,并且该节点的Name时固定的。提取文件之前先访问该节点,获取每个文件的文件名,然后把文件名作为节点的Name去获取对对应的二进制。其实上一篇打包的代码中我们已经考虑到这一点了,我们将所有的文件名存入了一个Name为"^FileNames^"的节点中。
这时我们就可以写提取的方法了,如下:
private bool ExtractFiles() { ResourceManager resManager = new ResourceManager("WinditeInstaller.FileList", typeof(FormInstallerBase).Assembly); string fileNames = resManager.GetString(NODE_FILENAMES); string[] fileNameArray = fileNames.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); string fileName = ""; if (fileNameArray.Length == 0) { return true; } string installLocation = this.TLocation.Text; string filePath = ""; try { if (!System.IO.Directory.Exists(installLocation)) { System.IO.Directory.CreateDirectory(installLocation); this._currentStep += 1; this.RefreshProgress(); } for (int i = 0; i < fileNameArray.Length; i++) { fileName = fileNameArray[i].Trim(); filePath = System.IO.Path.Combine(installLocation, fileName); System.IO.File.WriteAllBytes(filePath, (byte[])resManager.GetObject(fileName)); _extractedFiles.Add(filePath); this._currentStep += 1; this.RefreshProgress(); } } catch (Exception e) { MessageBox.Show(e.ToString()); return false; } return true; } }
本文章由创风网原创,转载请注明出处:http://www.windite.com/article/details/rlwv2d16