从主项目中查找 Class 个库的资源

Find resources of Class Library from Main Project

问题

我的解决方案由几个项目组成。 UI 的主要部分我们将称为 Assistant,而后端我们将称为 AssistantLib。

结构如下:

在 AssistantLib 中,我将 PDF 作为资源包含在 Resources 文件夹中,Build ActionContentCopy to Output DirectoryCopy Always 。通过使用这些组合进行调试时,我能够找到它们:

    private string GetArtifactPath(string artifactName)
    {
        return Path.Combine(GetResourcePath(), artifactName);
    }

    public static string GetResourcePath()
    {
        return Path.Combine(Directory.GetCurrentDirectory(), "Resources");
    }

这行得通。一旦我 return 来自 GetArtifactPath 的字符串,我用 Process 对象和 AcroRd32.exe.

打开文件

请注意,我需要通过文件路径来引用这些文件。它们不是简单的文本文件来阅读或流式传输。我还需要能够使用 AcroRd32.exe 提供的特定标志打开它们。这意味着我必须有文件路径

我遇到的问题是,一旦我发布了 ClickOnce 应用程序,我就收到了找不到文件的错误消息:

Error: Could not find a part of the path 'C:\Users\EL-C\AppData\Local\Apps.0JCPDD49.7G522AMZE.NZL\azte..tion_edea8654ffceff97_0001.0000_447ed0da08290357\Resources\Guidelines.2'.. Stacktrace:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

当然,当我去那个位置时,资源不在那里。

我试过的

更新

我正在调查 post-构建事件。在这样做的过程中,我发现这些资源 already 在构建之后的输出目录中:

但由于某些原因,当我发布时它们没有出现:

更新 2

为了说明文件夹结构如何影响这一点,这里是之前和之后。

当资源在 AssistantLib 中时(例如 EVMSBP),这是结构:

这是使用 AssistantLib 中的资源安装后 ClickOnce 发布文件夹的样子:

或者,当资源位于 Assistant(同样是 EVMSBP)时,结构如下:

下面是使用 Assistant 中的资源安装后 ClickOnce 发布文件夹的样子:

据我所知,资源必须是启动项目的一部分。这听起来像精神错乱?

我错过了什么?

当我使用 visual studio 设置以 exe 格式构建项目时,我遇到了同样的问题,我只是在项目构建输出目录中添加 pdf 文件。您必须将 pdf 文件夹复制到 binrelease 文件夹中,然后使用 ~ 根目录获取文件

随着编辑的更多细节,这就是我复制它的方式

  • AssistLib项目中

    • 资源中的文件 Build ActionEmbedded Resources
    • Output Type: Class Library (AssistLib.dll)

    • 见Solution Structure


  • AzTech主项目中
    • 我参考了 AssistLib.dll
    • 检查我要加载的资源 (pdf)是否存在于AssistLib.dll
    • 加载资源
    • 启动 PDF
    • 到目前为止还不错
    • 我发布了应用程序并安装了
    • 我从“开始”菜单上的图标启动了应用程序
    • 启动作为资源嵌入到 DLL 中的 PDF


AzTech.cs

var nameOfTheFile = "test.pdf";
ResourceManager.GetResourceInfo(nameOfTheFile);
if (ResourceManager.resourceExists == false)
{ Console.WriteLine("Specified PDF file not found"); return; }

Console.WriteLine("Resouce found in DLL");
ResourceManager.LoadResource(nameOfTheFile);//Will load the pdf in your main project

Process.Start(nameOfTheFile);

 class ResourceManager
 {
        public static bool resourceExists { get; set; } = false;
        private static Stream resourceStream { get; set; }
        public static void GetResourceInfo(string fileNameWithExtension)
        {
            const string pathToResource = "AssistantLib.Resources.Guidelines";

            var assembly = Assembly.Load("AssistantLib");
            //var names = assembly.GetManifestResourceNames();
            var stream = assembly.GetManifestResourceStream($"{pathToResource}.{fileNameWithExtension}");
            if (stream == null)
                return;

            resourceExists = true;

            resourceStream = stream;

        }

        public static void LoadResource(string newFileNameWithExtension)
        {
            if(File.Exists(newFileNameWithExtension))
            {
                Console.WriteLine("File already exists");
                return;
            }
            using (Stream s = File.Create(newFileNameWithExtension))
            {
                Console.WriteLine("Loading file");
                resourceStream.CopyTo(s);
            }
        }
 }