根据URI检测WPF资源是否存在

发布于 2024-08-16 19:44:10 字数 908 浏览 6 评论 0原文

给定 pack:// URI,判断该 URI 中是否实际存在已编译资源(例如,使用“Resource”构建操作编译的 PNG 图像)的最佳方法是什么?

经过一番摸索后,我想出了这段代码,它可以工作,但很笨拙:

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

(请注意 Application.GetResources 文档错误< /a> - 如果找不到资源,它会抛出异常,而不是像文档错误地声明的那样返回 null。) (文档已更正,请参阅下面的评论)

我不喜欢捕获异常来检测预期的(非异常)结果。此外,我实际上不想加载流,我只是想知道它是否存在。

有没有更好的方法来做到这一点,也许使用较低级别的资源 API——理想情况下不需要实际加载流并且不会捕获异常?

Given a pack:// URI, what's the best way to tell whether a compiled resource (e.g. a PNG image, compiled with a Build Action of "Resource") actually exists at that URI?

After some stumbling around, I came up with this code, which works but is clumsy:

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

(Note that the Application.GetResources documentation is wrong -- it throws an exception if the resource isn't found, rather than returning null like the docs incorrectly state.) (The docs have been corrected, see comments below)

I don't like catching exceptions to detect an expected (non-exceptional) result. And besides, I don't actually want to load the stream, I just want to know whether it exists.

Is there a better way to do this, perhaps with lower-level resource APIs -- ideally without actually loading the stream and without catching an exception?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猥琐帝 2024-08-23 19:44:10

我找到了一个正在使用的解决方案,它不能直接与 Pack Uri 一起使用,而是通过资源路径查找资源。话虽这么说,这个示例可以很容易地修改为支持 Pack URI,而只需将资源路径附加到 uri 的末尾,该 uri 使用程序集来制定 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();
    }
}

I've found a solution that I'm using which doesn't work directly with a pack Uri but instead looks up a resource by it's resource path. That being said, this example could be modified pretty easily to support a pack URI instead by just tacking on the resource path to the end of a uri which uses the Assembly to formulate the base part of the 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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文