Как получить объект потока из файла ресурсов (консольное приложение / проект службы Windows)

Я создаю службу Windows и пытаюсь получить доступ к некоторым файлам, которые я добавил в файл ресурсов, но я застрял, потому что не знаю, как получить доступ к отдельные файлы. Просто для справки, вот что я сделал до сих пор:

  • Это приложение службы Windows на C #, работающее в режиме отладки в качестве консольного приложения, которое помогает мне войти в код.

  • Я добавил в корень файл ресурсов под названием «Resources.resx».

  • В свой файл ресурсов я добавил несколько изображений jpg и html файлов с помощью визуального дизайнера / редактора.

  • После того, как я добавил изображения и html-файлы в файл ресурсов, в моем проекте появилась новая папка с именем «Ресурсы» со всеми добавленными мною файлами.

  • В этой новой папке я перешел к свойствам каждого файла и изменил действие сборки на встроенный ресурс. (Я не знаю, нужно ли это. В одном блоге, который я искал, предлагалось попробовать.)

  • Пространство имен проекта называется «MicroSecurity.EmailService».

  • Чтобы получить имя файла ресурсов, я использовал

    GetType (). Assembly.GetManifestResourceNames ()

и получил следующее

GetType (). Assembly.GetManifestResourceNames () {строка [2]} строка [] [0] «MicroSecurity.EmailService.Services.EmailService.resources» строка [1] «MicroSecurity.EmailService.Resources.resources» строка

Из этого Я определил, что "MicroSecurity.EmailService.Resources.resources "- строка, которую я хочу использовать (индекс 1).

  • Я использовал этот код для получения объекта потока.

    var stream = Assembly.GetExecutingAssembly (). GetManifestResourceStream (" MicroSecurity.EmailService .Resources.resources ");

Когда я добавляю часы к этой переменной во время отладки, я могу видеть такие вещи, как метаданные для моих изображений и т. Д.

Вот где я застрял. Я хотел бы получить доступ изображение называется "logo.jpg". Это то, что я делаю, чтобы получить изображение, но оно не работает.

var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MicroSecurity.EmailService.Resources.resources.logo.jpg");

Как я могу получить поток из моего файла logo.jpg?

ОБНОВЛЕНИЕ:

] Благодаря Эндрю мне удалось это выяснить. Ниже приведен код, который я написал для демонстрационного проекта, чтобы изучить, как работает файл ресурсов по сравнению с непосредственным встраиванием файлов. Надеюсь, это поможет другим прояснить различия.

using System;
using System.Drawing;
using System.IO;
using System.Reflection;

namespace UsingResourceFiles
{
    public class Program
    {
        /// <summary>
        /// Enum to indicate what type of file a resource is.
        /// </summary>
        public enum FileType
        {
            /// <summary>
            /// The resource is an image.
            /// </summary>
            Image,

            /// <summary>
            /// The resource is something other than an image or text file.
            /// </summary>
            Other,

            /// <summary>
            /// The resource is a text file.
            /// </summary>
            Text,           
        }

        public static void Main(string[] args)
        {
            // There are two ways to reference resource files:
            // 1. Use embedded objects.
            // 2. Use a resource file.

            // Get the embedded resource files in the Images and Text folders.
            UseEmbeddedObjects();

            // Get the embedded resource files in the Images and Text folders. This allows for dynamic typing
            // so the resource file can be returned either as a stream or an object in its native format.
            UseEmbeddedObjectsViaGetResource();

            // Use the zombie.gif and TextFile.txt in the Resources.resx file.
            UseResourceFile();
        }

        public static void UseEmbeddedObjects()
        { 
            // =============================================================================================================================
            //
            //                                                     -=[ Embedded Objects ]=-
            //
            // This way is the easiest to accomplish. You simply add a file to your project in the directory of your choice and then 
            // right-click the file and change the "Build Action" to "Embedded Resource". When you reference the file, it will be as an 
            // unmanaged stream. In order to access the stream, you'll need to use the GetManifestResourceStream() method. This method needs
            // the name of the file in order to open it. The name is in the following format:
            //
            // Namespace + Folder Path + File Name
            //
            // For example, in this project the namespace is "UsingResourceFiles", the folder path is "Images" and the file name is 
            // "zombie.gif". The string is "UsingResourceFiles.Images.zombie.gif". 
            //
            // For images, once the image is in a stream, you'll have to convert it into a Bitmap object in order to use it as an Image
            // object. For text, you'll need to use a StreamReader to get the text file's text.
            // =============================================================================================================================
            var imageStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("UsingResourceFiles.Images.zombie.gif");
            var image = new Bitmap(imageStream);

            var textStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("UsingResourceFiles.Text.TextFile.txt");
            var text = new StreamReader(textStream).ReadToEnd();
        }

        public static void UseEmbeddedObjectsViaGetResource()
        {
            // =============================================================================================================================
            //
            //                                             -=[ Embedded Objects Using GetResource() ]=-
            //
            // Using the overloaded GetResource() method, you can easily obtain an embedded resource file by specifying the dot file path
            // and type. If you need the stream version of the file, pass in false to the useNativeFormat argument. If you use the
            // GetResource() method outside of this file and are getting a null value back, make sure you set the resource's "Build Action"
            // to "Embedded Resource".
            // =============================================================================================================================

            // Use the GetResource() methods to obtain the Images\zombie.gif file and the text from the Text\TextFile.txt file.
            Bitmap image = GetResource("Images.zombie.gif", FileType.Image);
            Stream imageStream = GetResource("Images.zombie.gif", FileType.Image, false);

            string text = GetResource("Text.TextFile.txt", FileType.Text);
            Stream textStream = GetResource("Text.TextFile.txt", FileType.Text, false);
        }

        public static void UseResourceFile()
        {
            // =============================================================================================================================
            //
            //                                                      -=[ Resource File ]=-
            //
            // This way takes more upfront work, but referencing the files is easier in the code-behind. One drawback to this approach is
            // that there is no way to organize your files in a folder structure; everything is stuffed into a single resource blob.
            // Another drawback is that once you create the resource file and add any files to it, a folder with the same name as your
            // resource file is created, creating clutter in your project. A final drawback is that the properties of the Resources object
            // may not follow proper C# naming conventions (e.g. "Resources.funny_man" instead of "Resources.FunnyMan"). A plus for using
            // resource files is that they allow for localization. However, if you're only going to use the resource file for storing files,
            // using the files as embedded objects is a better approach in my opinion.
            // =============================================================================================================================

            // The Resources object references the resource file called "Resources.resx".
            // Images come back as Bitmap objects and text files come back as string objects.
            var image = Resources.zombie;
            var text = Resources.TextFile;
        }

        /// <summary>
        /// This method allows you to specify the dot file path and type of the resource file and return it in its native format.
        /// </summary>
        /// <param name="dotFilePath">The file path with dots instead of backslashes. e.g. Images.zombie.gif instead of Images\zombie.gif</param>
        /// <param name="fileType">The type of file the resource is.</param>
        /// <returns>Returns the resource in its native format.</returns>
        public static dynamic GetResource(string dotFilePath, FileType fileType)
        {
            try
            {
                var assembly = Assembly.GetExecutingAssembly();
                var assemblyName = assembly.GetName().Name;
                var stream = assembly.GetManifestResourceStream(assemblyName + "." + dotFilePath);
                switch (fileType)
                { 
                    case FileType.Image:                    
                        return new Bitmap(stream);
                    case FileType.Text:
                        return new StreamReader(stream).ReadToEnd();
                    default:
                        return stream;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return null;
            }
        }

        /// <summary>
        /// This method allows you to specify the dot file path and type of the resource file and return it in its native format.
        /// </summary>
        /// <param name="dotFilePath">The file path with dots instead of backslashes. e.g. Images.zombie.gif instead of Images\zombie.gif</param>
        /// <param name="fileType">The type of file the resource is.</param>
        /// <param name="useNativeFormat">Indicates that the resource is to be returned as resource's native format or as a stream.</param>
        /// <returns>When "useNativeFormat" is true, returns the resource in its native format. Otherwise it returns the resource as a stream.</returns>
        public static dynamic GetResource(string dotFilePath, FileType fileType, bool useNativeFormat)
        {
            try
            {
                if (useNativeFormat)
                {
                    return GetResource(dotFilePath, fileType);
                }

                var assembly = Assembly.GetExecutingAssembly();
                var assemblyName = assembly.GetName().Name;
                return assembly.GetManifestResourceStream(assemblyName + "." + dotFilePath);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return null;
            }
        }
    }
}
9
задан Halcyon 13 October 2011 в 22:52
поделиться