找不到项目 DLL 中嵌入的 .XSL 文件

Can't find .XSL file embedded in project DLL

一个简单的问题让我整个早上都崩溃了,快把我逼疯了。

我有一个小项目,其中包含来自另一个项目的 DLL。 DLL 中嵌入了一个 XSL 文件,我想将其提取并应用于网络浏览器控件。

我在主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

指定的资源文件操作为"Embedded Resource",位于DLL工程的"root"区域

访问 global:: 为我提供 CobCommonDataBuilder 可用选项,但 CobCommon 没有 .Properties.Resources 选项,DataBuilder.Properties.Resources 给出 "Culture"作为唯一参考。

XSL 文件 列在 DLL 项目的 "Properties|Resources|Files" 选项卡上。

我错过了什么?

使用 GetExecutingAssembly() 可能总是指 您的 程序集。相反,创建在该外部 DLL 中声明的一些无害的(希望如此)简单对象的实例,然后使用该实例对象的...

<object-from-DLL>.GetType().Assembly.GetManifestResourceStream("what.youre.looking.for") 

获取嵌入对象的流句柄。

所以这就是我最终设法组合一个通用函数以从任何项目程序集中检索 any text-encoded 嵌入式资源的方法(并且按预期工作在我的项目中):

首先,我扩展了 Assembly class 以便于只抓取我们需要用来搜索所请求资源的 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;
}

然后我写了这个函数来搜索指定的程序集+嵌入的资源文件并且return它的内容是一个字符串,如果找到:

/// <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.");
}