一个困扰我早晨的简短问题,使我发疯。
我有一个小项目,其中包含另一个项目的DLL。 DLL中嵌入了一个XSL文件,我要提取该文件并将其应用于Web浏览器控件。
我在提取/访问主EXE文件中的嵌入式资源方面没有问题,但是我无法在DLL中找到访问它的方法!?
我尝试过:
...及其几乎所有排列,但永远找不到。
我在C#中没有可与nameof()
一起使用的点符号引用,并且我找不到任何明显的引用/对它的访问:
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
那么,检索此文件的正确命名(或其他方法)是什么?
万一这有帮助,以下是一些其他详细信息:
项目名称: DataBuilder
项目命名空间: DataBuilder
DLL名称:: CobCommon
DLL命名空间: CobCommon,CobCommon.Classes,CobCommon.Classes.Data,CobCommon.Winforms,CobCommon.WinForms.Controls
XSL资源名称: XmlFormating.xsl
指定的资源文件操作为“嵌入式资源”,位于DLL项目的“根”区域。
访问global::
可以为我提供 CobCommon 和 DataBuilder ,但 CobCommon 都没有{ {1}}或.Properties
选项,而确实具有.Resources
的 DataBuilder 提供了“文化”作为唯一参考。
在DLL项目的“属性|资源|文件”选项卡上列出了XSL文件 。
我想念什么?
答案 0 :(得分:2)
使用GetExecutingAssembly()
可能总是引用您的程序集。而是创建一个在该外部DLL中声明的无害(希望)简单对象的实例,然后使用该实例对象的...
<object-from-DLL>.GetType().Assembly.GetManifestResourceStream("what.youre.looking.for")
获取嵌入式对象的流句柄。
答案 1 :(得分:0)
所以这是我最终设法组合一个通用函数从任何项目程序集中检索任何文本编码的嵌入式资源的方式(并且按我的项目的预期工作):>
首先,我扩展了Assembly
类,以便于仅抓取我们用来搜索所请求资源所需的Assembly.FullName
的相关主要部分:
/// <summary>Adds a function to dereference just the base name portion of an Assembly from the FullName.</summary>
/// <returns>The extracted base name if able, otherwise just the FullName.</returns>
public static string ExtractName(this Assembly root)
{
string pattern = @"^(?<assy>(?:[a-zA-Z\d]+[.]?)+)(?>,).*$", work = root.FullName;
MatchCollection matches = Regex.Matches(work, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
if (matches.Count > 0) return matches[0].Groups["assy"].Value;
if (work.IndexOf(",") > 3) return work.Substring(0, work.IndexOf(','));
return root.FullName;
}
然后,我编写了此函数来搜索指定的程序集+嵌入式资源文件,并以字符串形式返回其内容(如果找到):
/// <summary>Searches all loaded assemblies in a project for the specified embedded resource text file.</summary>
/// <returns>If the specified resource is found, its contents as a string, otherwise throws a DllNotFoundException.</returns>
/// <exception cref="DllNotFoundException"></exception>
public static string FetchAssemblyResourceFile(string name)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
int i = -1; while ((++i < assemblies.Length) && !Regex.IsMatch(name, "^(" + assemblies[i].ExtractName() + ")", RegexOptions.IgnoreCase)) ;
if (i < assemblies.Length)
{
try {
using (System.IO.Stream stream = assemblies[i].GetManifestResourceStream(name))
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
return reader.ReadToEnd();
}
catch (Exception innerExc)
{
Exception result = new Exception("The requested resource (\"" + name + "\") was not found.");
result.InnerException = innerExc;
throw result;
}
}
throw new DllNotFoundException("The requested assembly resource (\"" + name + "\") could not be found.");
}