Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从包含其程序集和任何程序集路径的Uri加载资源?_C#_File_Resources_Uri_.net Assembly - Fatal编程技术网

C# 如何从包含其程序集和任何程序集路径的Uri加载资源?

C# 如何从包含其程序集和任何程序集路径的Uri加载资源?,c#,file,resources,uri,.net-assembly,C#,File,Resources,Uri,.net Assembly,我想仅使用其uri从任何程序集(同一应用程序)加载任何资源。两个程序集都是同一应用程序的一部分 因为我希望能够从任何程序集加载,所以我不能使用未在常规Dll中定义的“应用程序”或“应用程序” 我认为部分或答案是使用:System.Reflection.Assembly.GetCallingAssembly().GetManifestResourceStream(路径) 但是我找不到如何正确地从uri中查找/提取/解析程序集 注: 资源实际上被定义为“资源” 资源不是WPF资源字典的PAR。 资

我想仅使用其uri从任何程序集(同一应用程序)加载任何资源。两个程序集都是同一应用程序的一部分

因为我希望能够从任何程序集加载,所以我不能使用未在常规Dll中定义的“应用程序”或“应用程序”

我认为部分或答案是使用:
System.Reflection.Assembly.GetCallingAssembly().GetManifestResourceStream(路径)

但是我找不到如何正确地从uri中查找/提取/解析程序集

注:

  • 资源实际上被定义为“资源”
  • 资源不是WPF资源字典的PAR。
  • 资源实际上是一个XML文件,但可以是任何内容

到目前为止(大约3小时后),在使用reflector之后,似乎使用静态System.Windows.Application.GetResourceStream(uri).Stream具有资源缓存等优点。这是不好的,因为它连接到WPF(System.windows)。我正在寻找更好的方法(不依赖于任何特定的UI框架)来完成这项工作。

我使用下面定义的“LoadResourceFromUri”函数解决了我的问题。我在上完成并发布了一个项目,该项目使用一个工具加载任何模块(dll)并显示其资源。还可以获取有关uri的信息

在将byteArray转换为stream时,我使用了大约4的偏移量,因为否则(没有偏移量),它就不能按预期工作

使用系统;
使用系统集合;
使用System.Collections.Generic;
使用系统诊断;
使用系统图;
使用System.IO;
使用System.Linq;
运用系统反思;
利用系统资源;
使用System.Runtime.Serialization.Formatters.Binary;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Resources;
命名空间HQ.Util.General
{
公共静态类ResourceHelper
{
// ******************************************************************
/// 
///资源应定义为“资源”,而不是“嵌入式资源”。
/// 
///资源路径
///如果为null,则使用调用程序集查找资源
/// 
公共静态Uri GetLocationUri(字符串resourcePath,程序集=null)
{
if(assembly==null)
{
assembly=assembly.GetCallingAssembly();
}
resourcePath=resourcePath.Replace('\\','/');
返回新Uri(@)pack://application:,,,/“+assembly.GetName().Name+”“组件”+
(resourcePath[0]=='/'?resourcePath:“/”+resourcePath),UriKind.Absolute);
}
// ******************************************************************
/// 
///将从属于应用程序的任何程序集加载资源。
///它不依赖于特定于(UI)框架工作的应用程序。
/// 
/// 
/// 
/// 
公共静态流LoadResourceFromUri(Uri,程序集asm=null)
{
Stream=null;
if(uri.Authority.StartsWith(“应用程序”)和uri.Scheme==“包”)
{
字符串localPath=uri.GetComponents(UriComponents.Path,UriFormat.UriEscape);
int indexlocalpathwhithoutassembly=localPath.IndexOf(“;component/”);
if(无组件的INDEXLOCALPATH==-1)
{
indexLocalPathWithoutAssembly=0;
}
其他的
{
INDEXLOCALPATHOWTHOUTHASSEMBLY+=11;
}
如果(asm!=null)//获取提供的程序集,则不要在uri中检查asm。
{
stream=GetAssemblyResourceStream(asm,localPath.Substring(IndexLocalPasthWithoutAssembly));
}
其他的
{
如果(uri.Segments.Length>1)
{
if(uri.Segments[0]==“/”&&uri.Segments[1].EndsWith(“;component/”)
{
int index=uri.Segments[1].IndexOf(“;”);
如果(索引>0)
{
字符串assemblyName=uri.Segments[1]。子字符串(0,索引);
foreach(AppDomain.CurrentDomain.GetAssemblys()中的程序集asmIter)
{
if(asmIter.GetName().Name==assemblyName)
{
stream=GetAssemblyResourceStream(asmIter,localPath.Substring(indexLocalPathWithoutAssembly));
打破
}
}
}
}
}
if(流==null)
{
asm=Assembly.GetCallingAssembly();
stream=GetAssemblyResourceStream(asm,localPath.Substring(IndexLocalPasthWithoutAssembly));
}
}
}
回流;
}
// ******************************************************************
/// 
///路径分隔符为“/”。路径不应以“/”开头。
/// 
/// 
/// 
/// 
公共静态流GetAssemblyResourceStream(程序集asm,字符串路径)
{
//只是想确定一下
如果(路径[0]=='/'))
{
路径=路径子字符串(1);
}
//只是想确定一下
if(path.IndexOf('\\')==-1)
{
path=path.Replace('\\','/');
}
Stream resStream=null;
字符串resName=asm.GetName().Name+”.g.re
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Resources;

namespace HQ.Util.General
{
    public static class ResourceHelper
    {
        // ******************************************************************
        /// <summary>
        /// The resource should be defined as 'Resource' not as 'Embedded resource'.
        /// </summary>
        /// <param name="resourcePath">The resource path</param>
        /// <param name="assembly">If null, then use calling assembly to find the resource</param>
        /// <returns></returns>
        public static Uri GetLocationUri(string resourcePath, Assembly assembly = null)
        {
            if (assembly == null)
            {
                assembly = Assembly.GetCallingAssembly();
            }

            resourcePath = resourcePath.Replace('\\', '/');

            return new Uri(@"pack://application:,,,/" + assembly.GetName().Name + ";component" +
                (resourcePath[0] == '/' ? resourcePath : "/" + resourcePath), UriKind.Absolute);
        }

        // ******************************************************************
        /// <summary>
        /// Will load resource from any assembly that is part of the application.
        /// It does not rely on Application which is specific to a (UI) frameowrk.
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="asm"></param>
        /// <returns></returns>
        public static Stream LoadResourceFromUri(Uri uri, Assembly asm = null)
        {
            Stream stream = null;

            if (uri.Authority.StartsWith("application") && uri.Scheme == "pack")
            {
                string localPath = uri.GetComponents(UriComponents.Path, UriFormat.UriEscaped);

                int indexLocalPathWithoutAssembly = localPath.IndexOf(";component/");
                if (indexLocalPathWithoutAssembly == -1)
                {
                    indexLocalPathWithoutAssembly = 0;
                }
                else
                {
                    indexLocalPathWithoutAssembly += 11;
                }

                if (asm != null) // Take the provided assembly, do not check for the asm in the uri.
                {
                    stream = GetAssemblyResourceStream(asm, localPath.Substring(indexLocalPathWithoutAssembly));
                }
                else
                {
                    if (uri.Segments.Length > 1)
                    {
                        if (uri.Segments[0] == "/" && uri.Segments[1].EndsWith(";component/"))
                        {
                            int index = uri.Segments[1].IndexOf(";");
                            if (index > 0)
                            {
                                string assemblyName = uri.Segments[1].Substring(0, index);

                                foreach (Assembly asmIter in AppDomain.CurrentDomain.GetAssemblies())
                                {
                                    if (asmIter.GetName().Name == assemblyName)
                                    {
                                        stream = GetAssemblyResourceStream(asmIter, localPath.Substring(indexLocalPathWithoutAssembly));
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (stream == null)
                    {
                        asm = Assembly.GetCallingAssembly();
                        stream = GetAssemblyResourceStream(asm, localPath.Substring(indexLocalPathWithoutAssembly));
                    }
                }
            }
            return stream;
        }

        // ******************************************************************
        /// <summary>
        /// The path separator is '/'.  The path should not start with '/'.
        /// </summary>
        /// <param name="asm"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public static Stream GetAssemblyResourceStream(Assembly asm, string path)
        {
            // Just to be sure
            if (path[0] == '/')
            {
                path = path.Substring(1);
            }

            // Just to be sure
            if (path.IndexOf('\\') == -1)
            {
                path = path.Replace('\\', '/');
            }

            Stream resStream = null;

            string resName = asm.GetName().Name + ".g.resources"; // Ref: Thomas Levesque Answer at:
            // http://stackoverflow.com/questions/2517407/enumerating-net-assembly-resources-at-runtime

            using (var stream = asm.GetManifestResourceStream(resName))
            {
                using (var resReader = new System.Resources.ResourceReader(stream))
                {
                    string dataType = null;
                    byte[] data = null;
                    try
                    {
                        resReader.GetResourceData(path.ToLower(), out dataType, out data);
                    }
                    catch (Exception ex)
                    {
                        DebugPrintResources(resReader);
                    }

                    if (data != null)
                    {
                        switch (dataType) // COde from 
                        {
                            // Handle internally serialized string data (ResourceTypeCode members).
                            case "ResourceTypeCode.String":
                                BinaryReader reader = new BinaryReader(new MemoryStream(data));
                                string binData = reader.ReadString();
                                Console.WriteLine("   Recreated Value: {0}", binData);
                                break;
                            case "ResourceTypeCode.Int32":
                                Console.WriteLine("   Recreated Value: {0}", BitConverter.ToInt32(data, 0));
                                break;
                            case "ResourceTypeCode.Boolean":
                                Console.WriteLine("   Recreated Value: {0}", BitConverter.ToBoolean(data, 0));
                                break;
                            // .jpeg image stored as a stream.
                            case "ResourceTypeCode.Stream":
                                ////const int OFFSET = 4;
                                ////int size = BitConverter.ToInt32(data, 0);
                                ////Bitmap value1 = new Bitmap(new MemoryStream(data, OFFSET, size));
                                ////Console.WriteLine("   Recreated Value: {0}", value1);

                                const int OFFSET = 4;
                                resStream = new MemoryStream(data, OFFSET, data.Length - OFFSET);

                                break;
                            // Our only other type is DateTimeTZI.
                            default:
                                ////// No point in deserializing data if the type is unavailable.
                                ////if (dataType.Contains("DateTimeTZI") && loaded)
                                ////{
                                ////    BinaryFormatter binFmt = new BinaryFormatter();
                                ////    object value2 = binFmt.Deserialize(new MemoryStream(data));
                                ////    Console.WriteLine("   Recreated Value: {0}", value2);
                                ////}
                                ////break;
                                break;
                        }

                        // resStream = new MemoryStream(resData);
                    }
                }
            }

            return resStream;
        }

        // ******************************************************************
        private static void DebugPrintResources(System.Resources.ResourceReader reader)
        {
            Debug.Print("Begin dump resources: ---------------------");
            foreach (DictionaryEntry item in reader)
            {
                Debug.Print(item.Key.ToString());
            }
            Debug.Print("End   dump resources: ---------------------");
        }

        // ******************************************************************        // ******************************************************************
    }
}