我目前使用GetManifestResourceStream来访问嵌入资源。资源的名称来自不区分大小写的外部源。有没有办法以不区分大小写的方式访问嵌入式资源?
我宁愿不必仅使用小写字母来命名我的所有嵌入资源。
答案 0 :(得分:11)
假设您知道来自外部源的资源名称且仅缺少大小写,此函数会创建一个字典,您可以使用该字典进行查找以对齐这两组名称。
you know -> externally provided
MyBitmap -> MYBITMAP
myText -> MYTEXT
/// <summary>
/// Get a mapping of known resource names to embedded resource names regardless of capitlalization
/// </summary>
/// <param name="knownResourceNames">Array of known resource names</param>
/// <returns>Dictionary mapping known resource names [key] to embedded resource names [value]</returns>
private Dictionary<string, string> GetEmbeddedResourceMapping(string[] knownResourceNames)
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
string[] resources = assembly.GetManifestResourceNames();
Dictionary<string, string> resourceMap = new Dictionary<string, string>();
foreach (string resource in resources)
{
foreach (string knownResourceName in knownResourceNames)
{
if (resource.ToLower().Equals(knownResourceName.ToLower()))
{
resourceMap.Add(knownResourceName, resource);
break; // out of the inner foreach
}
}
}
return resourceMap;
}
答案 1 :(得分:2)
如果您不想提前创建字典,那么这将有效。
private static Stream GetResourceStream(string name)
{
var assembly = Assembly.GetExecutingAssembly();
//Replace path seperators with '.' seperators
var path = string
.Concat( assembly.GetName().Name, ".", name)
.Replace('/','.')
.Replace('\\','.');
// Match using case invariant matching
path = assembly
.GetManifestResourceNames()
.FirstOrDefault(p => p.ToLowerInvariant() == path.ToLowerInvariant());
if(path==null)
throw new ArgumentNullException($"Can't find resource {name}",nameof(name));
var manifestResourceStream = assembly.GetManifestResourceStream(path);
if (manifestResourceStream == null)
throw new ArgumentNullException($"Can't find resource {name}",nameof(name));
return manifestResourceStream;
}
答案 2 :(得分:0)
上面接受的类似答案,但我想在VB.NET中分享我的解决方案。
''' <summary>
''' Gets the file name in its proper case as found in the assembly.
''' </summary>
''' <param name="fileName">The filename to check</param>
''' <param name="assemblyNamespace">The namespace name, such as Prism.Common</param>
''' <param name="assembly">The assembly to search</param>
''' <returns>The file name as found in the assembly in its proper case, otherwise just filename as it is passed in.</returns>
''' <remarks></remarks>
Public Shared Function GetProperFileNameCaseInAssembly(ByVal fileName As String, ByVal assemblyNamespace As String, ByVal assembly As System.Reflection.Assembly) As String
For Each resource As String In assembly.GetManifestResourceNames()
'Perform a case insensitive search to get the correct casing for the filename
If (resource.ToLower().Equals(String.Format("{0}.{1}", assemblyNamespace, fileName).ToLower())) Then
'cut off the namespace assembly name in the resource (length + 1 to include the ".") to return the file name
Return resource.Substring(assemblyNamespace.Length + 1)
End If
Next
Return fileName 'couldn't find the equivalent, so just return the same file name passed in
End Function