2010-01-06 3 views
11

pack : // URI가 주어지면 컴파일 된 리소스 (예 : "리소스"빌드 동작으로 컴파일 된 PNG 이미지)가 실제로 해당 위치에 있는지 여부를 알 수있는 가장 좋은 방법은 무엇입니까? URI? 예외를 throw하는 자원이 발견되지 않는 경우 -URI를 기반으로 WPF 리소스가 있는지 여부를 감지합니다.

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

가합니다 (Application.GetResources 문서 is wrong이 있습니다 : 주위에 비틀 일부 후

, 나는 작동하지만 서투른이 코드를 함께했다 , 워드 프로세서처럼 null을 반환하는 대신 잘못 상태.)이 (워드 프로세서가 수정되었습니다 아래 설명 참조)

내가 예상 (비 예외적 인) 결과를 감지하는 예외를 잡기 좋아하지 않는다. 게다가 실제로 스트림을로드하고 싶지는 않습니다. 스트림이 있는지 여부를 알고 싶습니다.

저수준 리소스 API를 사용하는 것이 더 나은 방법일까요? 실제로 스트림을로드하지 않고 예외를 잡는 것이 가장 이상적입니까?

+0

그들은 리소스를 찾을 수 없을 때 예외를 throw한다는 문서를 업데이트했습니다. – Shimmy

+1

@Shimmy, 업데이트 주셔서 감사합니다. - 해당 정보를 포함하도록 편집했습니다. –

+0

@ 존 화이트 : BTW, 나는 당신이 [jpierson의 게시물] (http://stackoverflow.com/questions/2013481/detect-whether-wpf-resource-exists-based-on-uri/2549641#2549641)으로 표시해야한다고 생각합니다. 대답. – Shimmy

답변

10

내가 사용하고있는 솔루션이 패키지 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(); 
    } 
} 
+5

'GetResourcePaths'에서 반환 된 경로가 소문자 인 것처럼 보이므로'ResourceExists' 메서드에서'.Contains (resourcePath.ToLower()); '를 사용해야합니다. –

+2

안전을 위해서'.ToLowerInvariant()'를 만드십시오. – RandomEngy

관련 문제