// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. namespace System.Data.Entity { using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Resources; using System.Security; using System.Security.Permissions; #if !SILVERLIGHT #endif /// /// Various utilities for dealing with embedded resources /// public static class ResourceUtilities { #if !SILVERLIGHT /// /// Extracts the specified compressed resource to a given directory /// /// Output directory /// Assembly that contains the resource /// Partial resource name /// /// The method prefixes the actual resource with unqualified assembly name + '.Resources.' ( /// so you should put all your resources under 'Resources' directory within a project) /// and appends '.gz' to it. You should use gzip to produce compressed files. /// [SecuritySafeCritical] // Calling File.Create demands FileIOPermission (Write flag) for the file path to which the resource is extracted. [PermissionSet(SecurityAction.Assert, Unrestricted = true)] [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "gz", Justification = ".gz is GZIP file extension")] [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Bogus warning, object will be disposed once.")] public static void ExtractCompressedResourceToDirectory(string outputDirectory, Assembly assembly, string resourceName) { ValidateCommonArguments(outputDirectory, assembly, resourceName); var fullResourceName = new AssemblyName(assembly.FullName).Name + ".Resources." + resourceName + ".gz"; using (var compressedInputStream = assembly.GetManifestResourceStream(fullResourceName)) { if (compressedInputStream == null) { throw new IOException("Embedded resource " + fullResourceName + " not found in " + assembly.FullName); } using (var decompressedInputStream = new GZipStream(compressedInputStream, CompressionMode.Decompress)) { using (Stream outputStream = File.Create(Path.Combine(outputDirectory, resourceName))) { IOHelpers.CopyStream(decompressedInputStream, outputStream); } } } } #endif /// /// Copies the named embedded resources from given assembly into the current directory. /// /// The assembly. /// The prefix to use for each name. /// if set to true then an existing file of the same name name will be overwritten. /// The resource names, which will become the file names. public static void CopyEmbeddedResourcesToCurrentDir( Assembly assembly, string prefix, bool overwrite, params string[] names) { foreach (var name in names) { using (var sourceStream = assembly.GetManifestResourceStream(prefix + name)) { Debug.Assert(sourceStream != null, "Could not create stream for embedded resource " + prefix + name); var destinationPath = Path.Combine(@".\", name); if (!File.Exists(destinationPath) || overwrite) { using ( var destinationStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write)) { var sourceBuffer = new byte[sourceStream.Length]; sourceStream.Read(sourceBuffer, 0, sourceBuffer.Length); destinationStream.Write(sourceBuffer, 0, sourceBuffer.Length); } } } } } /// /// Builds a resource manager for the given assembly. /// /// The assembly to build the resource manager for. /// The resource manager. public static ResourceManager BuildResourceManager(Assembly assembly) { ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); return new ResourceManager(FindSingleResourceTable(assembly), assembly); } private static void ValidateCommonArguments(string outputDirectory, Assembly assembly, string resourceName) { ExceptionHelpers.CheckArgumentNotNull(outputDirectory, "outputDirectory"); ExceptionHelpers.CheckArgumentNotNull(assembly, "assembly"); ExceptionHelpers.CheckArgumentNotNull(resourceName, "resourceName"); if (!Directory.Exists(outputDirectory)) { throw new IOException("Output directory '" + outputDirectory + "' does not exist."); } } private static string FindSingleResourceTable(Assembly assembly) { var resources = assembly.GetManifestResourceNames().Where(r => r.EndsWith(".resources", StringComparison.Ordinal)); if (resources.Count() != 1) { throw new NotSupportedException( "The supplied assembly does not contain exactly one resource table, if the assembly contains multiple tables call the overload that specifies which table to use."); } var resource = resources.Single(); // Need to trim the ".resources" off the end return resource.Substring(0, resource.Length - 10); } } }