Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pack uri validation

Tags:

c#

uri

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

like image 957
Berryl Avatar asked Jun 10 '10 20:06

Berryl


2 Answers

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;
        }
    }
like image 89
Berryl Avatar answered Oct 22 '22 04:10

Berryl


Public Class Res

    Private Shared __keys As New List(Of String)

    Shared Function Exist(partName As String) As Boolean
        Dim r As Boolean = False

        If __keys.Count < 1 Then
            Dim a = Assembly.GetExecutingAssembly()
            Dim resourceName = a.GetName().Name + ".g"
            Dim resourceManager = New ResourceManager(resourceName, a)
            Dim resourceSet = resourceManager.GetResourceSet(Globalization.CultureInfo.CurrentCulture, True, True)
            For Each res As System.Collections.DictionaryEntry In resourceSet
                __keys.Add(res.Key)
            Next
        End If

        __keys.ForEach(Sub(e)
                           If e.Contains(partName.ToLower) Then
                               r = True
                               Exit Sub
                           End If
                       End Sub)

        Return r
    End Function
End Class
like image 1
bboyse Avatar answered Oct 22 '22 03:10

bboyse