给定一个pack:// URI,判断编译资源(例如,使用“资源”的构建操作编译的PNG图像)是否实际存在于该URI的最佳方法是什么?
经过一些磕磕绊绊之后,我想出了这个代码,它有效,但很笨拙:
private static bool CanLoadResource(Uri uri)
{
try
{
Application.GetResourceStream(uri);
return true;
}
catch (IOException)
{
return false;
}
}
(请注意Application.GetResources文档is wrong - 如果找不到资源,它会抛出异常,而不是像文档错误状态那样返回null。) (文档已更正,请参阅下面的评论)
我不喜欢捕获异常以检测预期(非异常)结果。此外,我实际上并不想加载流,我只是想知道它是否存在。
有没有更好的方法来实现这一点,可能使用较低级别的资源API - 理想情况下,没有实际加载流并且没有捕获异常?
答案 0 :(得分:10)
我找到了一个我正在使用的解决方案,它不能直接与包Uri一起工作,而是通过它的资源路径查找资源。话虽这么说,这个例子可以非常容易地修改以支持包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();
}
}