Обнаружьте, существует ли ресурс WPF, на основе URI

Учитывая pack://URI, что состоит в том, чтобы сказать лучший способ, существует ли скомпилированный ресурс (например, изображение PNG, скомпилированное с Действием Сборки "Ресурса") на самом деле, в том URI?

После некоторого спотыкания вокруг, я придумал этот код, который работает, но неуклюж:

private static bool CanLoadResource(Uri uri)
{
    try
    {
        Application.GetResourceStream(uri);
        return true;
    }
    catch (IOException)
    {
        return false;
    }
}

(Обратите внимание что Приложение. Документация GetResources является неправильной - она выдает исключение, если ресурс не найден, вместо того, чтобы возвратить пустой указатель как документы неправильно указывают.) (Документы были исправлены, см. комментарии ниже),

Мне не нравится ловить исключения для обнаружения ожидаемого (неисключительного) результата. И кроме того, я на самом деле не хочу загружать поток, я просто хочу знать, существует ли он.

Существует ли лучший способ сделать это, возможно, с API ресурса низшего уровня - идеально, на самом деле не загружая поток и не ловя исключение?

13
задан Joe White 26 October 2011 в 16:55
поделиться

1 ответ

Я нашел решение, которое использую, которое не работает напрямую с Uri пакета, а вместо этого ищет ресурс по его пути к ресурсу. При этом этот пример можно довольно легко изменить, чтобы вместо этого поддерживать URI пакета, просто прикрепив путь к ресурсу до конца uri, который использует Assembly для формулирования базовой части URI.

public static bool ResourceExists(string resourcePath)
{
    var assembly = Assembly.GetExecutingAssembly();

    return ResourceExists(assembly, resourcePath);
}

public static bool ResourceExists(Assembly assembly, string resourcePath)
{
    return GetResourcePaths(assembly)
        .Contains(resourcePath.ToLowerInvariant());
}

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

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

        foreach(System.Collections.DictionaryEntry resource in resourceSet)
        {
            yield return resource.Key;
        }
    }
    finally
    {
        resourceManager.ReleaseAllResources();
    }
}
11
ответ дан 2 December 2019 в 01:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: