tags:

views:

131

answers:

1

What is the simplest way to verify that a pack uri can be found?

For example, given

pack://application:,,,Rhino.Mocks;3.5.0.1337;0b3305902db7183f;component/SomeImage.png

how would I check whether the image actually exists?

Cheers,
Berryl

A: 

I couldn't find a simple answer to this, so I wound up rolling my own code to accomplish three things with respect to image resources:
(1) have a string representation of a pack uri (databind)
(2) verify that the image is located where I think it is located (unit test)
(3) verify that the pack uri can be used to set an image (unit test)

Part of the reason this isn't simple is because pack uri's are a bit confusing at first, and come in several flavors. This code is for a pack uri that represents an image that is included in a VS assembly (either locally or a referenced assembly with a build action of 'resource'. This msdn articles clarifies what that means in this context. You also need to understand more about assemblies and builds than might initially seem like a good time.

Hope this makes it easier for someone else. Cheers,
Berryl

    /// <summary> (1) Creates a 'Resource' pack URI .</summary>
    public static Uri CreatePackUri(Assembly assembly, string path, PackType packType)
    {
        Check.RequireNotNull(assembly);
        Check.RequireStringValue(path, "path");

        const string startString = "pack://application:,,,/{0};component/{1}";
        string packString;
        switch (packType)
        {
            case PackType.ReferencedAssemblySimpleName:
                packString = string.Format(startString, assembly.GetName().Name, path);
                break;
            case PackType.ReferencedAssemblyAllAvailableParts:
                // exercise for the reader
                break;
            default:
                throw new ArgumentOutOfRangeException("packType");
        }
        return new Uri(packString);
    }

    /// <summary>(2) Verify the resource is located where I think it is.</summary>
    public static bool ResourceExists(Assembly assembly, string resourcePath)
    {
        return GetResourcePaths(assembly).Contains(resourcePath.ToLowerInvariant());
    }

    public static IEnumerable<object> GetResourcePaths(Assembly assembly, CultureInfo culture)
    {
        var resourceName = assembly.GetName().Name + ".g";
        var resourceManager = new ResourceManager(resourceName, assembly);

        try
        {
            var resourceSet = resourceManager.GetResourceSet(culture, true, true);

            foreach (DictionaryEntry resource in resourceSet)
            {
                yield return resource.Key;
            }
        }
        finally
        {
            resourceManager.ReleaseAllResources();
        }
    }

    /// <summary>(3) Verify the uri can construct an image.</summary>
    public static bool CanCreateImageFrom(Uri uri)
    {
        try
        {
            var bm = new BitmapImage(uri);
            return bm.UriSource == uri;
        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
            return false;
        }
    }
Berryl