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