【问题标题】:Embed Text File in Resources在资源中嵌入文本文件
【发布时间】:2012-06-26 12:08:38
【问题描述】:

我试图将文本文件嵌入到我的资源文件中的应用程序中。不久前我在关注这个问题;

How to embed a text file in a .NET assembly?

我将我的文本文件添加到 Resources.resx,但无法理解如何在代码中调用它。如您所见,OP 遇到了同样的问题,并设法使用My.Resources.TEXTFILENAME 使其工作,而不是Resources.TEXTFILENAME 的最佳答案建议。不幸的是,在我的应用程序中两者都没有被识别,我已经尝试添加 usings 但 VS 没有任何建议。自己写Resources,它把它识别为ResourceDictionary和FrameworkElement.Resources,但没有文本文件……有什么想法吗?

【问题讨论】:

    标签: c# wpf visual-studio-2010 embedded-resource


    【解决方案1】:

    将文本文件添加到您的项目中,然后将其定义为内容 (Build Action=Content) 和 Copy always 到输出。

    如果您的项目有安装程序(标准安装程序),您可以设置文件系统,以便安装程序自动复制文本文件。

    要获取运行应用程序的文件夹,我使用这个:

    Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location);

    如果您使用的是新的安装程序 (ClicOnce),我无法帮助您,但祝您好运 :=)

    【讨论】:

    • 我实际上没有使用任何安装程序。只需使用我生成的 exe。
    • 但是那不会只是将文件复制到输出目录而不嵌入它吗?
    • @Nenotlep :我想你是对的。我必须是:Build Action=Resource / 并且不要复制。如果你确认我会更新,如果你能带来一些英特尔,请不要犹豫发布答案。
    【解决方案2】:

    如果文件很小,项目资源文件可以像其他人描述的那样使用,但这样文件只能作为 Unicode 字符串检索,可能/可能比原始文件大两倍并立即加载到内存中完整的。

    原始问题中提到的方法是将文本文件放在项目中的某个位置,在解决方案资源管理器中选择它,按 F4 显示属性,然后将 Build Action 设置为 嵌入资源并在请勿复制处留下复制到输出目录

    这与添加到您的 .csproj 相同:

    <ItemGroup>
        <EmbeddedResource Include="Resources\TextFile.txt"/>
    </ItemGroup>
    

    那么您将需要正确的AssemblyIFileProvider 的实例来按名称访问这些资源。

    通过组装:

    typeof(Program).Assembly.GetManifestResourceNames()
    typeof(Program).Assembly.GetManifestResourceStream(name)
    typeof(Program).Assembly.GetManifestResourceInfo(name)
    

    这些名称是类似的类名,以点分隔。如果您的项目是NamespaceName.ProjectName,则资源文件在Resources 子文件夹中,名为TextFile.txt,资源名称将是

    NamespaceName.ProjectName.Resources.TextFile.txt
    

    GetManifestResourceStream 有一个重载,它接受一个类型,所以你可以这样做

    typeof(Program).Assembly.GetManifestResourceStream(
        typeof(Program),
        "Resources.TextFile.txt")
    

    从不依赖默认命名空间或项目输出文件名。

    这些方法的缺点是它们似乎无法在监视窗口中工作。你可能会遇到异常

    System.ArgumentException "Cannot evaluate a security function."
    

    在这种情况下,只需将代码编写到您可以随意执行的地方 - 例如在静态方法中。这样代码就从你的程序集中运行,而不是调试器。

    通过IFileProvider

    dotnet add package Microsoft.Extensions.FileProviders.Embedded
    using Microsoft.Extensions.FileProviders;
    var fp = new EmbeddedFileProvider(typeof(Program).Assembly);
    // get all resources as an enumerable
    foreach (var fileInfo in fp.GetDirectoryContents(""))
        Console.WriteLine($"Name: {fileInfo.Name}, Length: {fileInfo.Length}, ...");
    // get a specific one by name
    var stream = fp.GetFileInfo("Resources.TextFile.txt").CreateReadStream();
    

    作为IFileProvider,您可能会尝试从纯嵌入式资源托管 .NET Core 网站。

    【讨论】:

      【解决方案3】:

      像这样嵌入文本资源似乎可行(visual c# express):

      1. 打开您的项目属性

      2. 浏览到资源,单击添加新并选择创建或添加现有资源,以正确者为准。

      3. 出现一个野生资源文件夹

      4. 像这样使用它们:

        string foo = global::[ProjectName].Properties.Resources.Muistio;
        string bar = global::[ProjectName].Properties.Resources.asd;
        

      资源构建操作为,复制到输出目录为不复制

      如果有人可以验证这一点,那就太好了,当 exe 传输到我的服务器 2k8 时它可以工作,但我仍然想要独立验证。特别是因为 ResourceHacker 没有看到字符串。

      【讨论】:

      • +1 有用的截图。此外,一个野生资源文件夹......太棒了。
      • 是的,但您不能流式传输它。您必须使用@Nenotlep 提到的属性,或使用 ResourceManager.GetString(name) 但这会产生一个 Unicode 字符串 - 可能比文件大两倍。
      • 这在 VS 2017 中对我有用。截图非常有用。
      【解决方案4】:

      使用 .ResX 资源与将文本文件嵌入到程序集中略有不同。对于后者,您需要检查其属性并将其设为EmbeddedResource(即,无需向 ResX 文件添加任何内容,只需将文本文件拖放到您的 VS 项目中即可)。要检索它,请使用:

      Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
      

      要获得 name 参数的正确值,请调用 GetManifestResourceNames() 并检查结果。

      【讨论】:

      • 嗯...所以我使用了Assembly.GetExecutingAssembly().GetManifestResourceStream("Explaination.txt"); 并且 Explaination.txt 在我的调试文件夹中,但是这一行似乎没有做任何事情。想法?
      • 请记住,我只想在记事本中打开文本文件。
      猜你喜欢
      • 2017-02-06
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多