从具有嵌入资源的程序集中读取

时间:2010-09-03 13:37:57

标签: embedded-resource .net-assembly

我构建了一个包含一个js文件的程序集。 我将该文件标记为Embedded Resource并将其添加到AssemblyInfo文件中。

我无法从网站上引用大会。它位于bin文件夹中,但我没有看到它的引用。

似乎没有在程序集中至少有一个类我无法引用它。

我会将js文件从程序集中包含到我的页面中。

我该怎么做?

由于

3 个答案:

答案 0 :(得分:3)

我在其中一个项目中做了同样的事情。我有一个中心ScriptManager类,它实际上会在脚本拉出时缓存脚本,但从嵌入式资源中提取脚本文件的核心如下所示:

internal static class ScriptManager
{
    private static Dictionary<string, string> m_scriptCache = 
                                     new Dictionary<string, string>();

    public static string GetScript(string scriptName)
    {
        return GetScript(scriptName, true);
    }

    public static string GetScript(string scriptName, bool encloseInCdata)
    {
        StringBuilder script = new StringBuilder("\r\n");

        if (encloseInCdata)
        {
            script.Append("//<![CDATA[\r\n");

        }

        if (!m_scriptCache.ContainsKey(scriptName))
        {
            var asm = Assembly.GetExecutingAssembly();

            var stream = asm.GetManifestResourceStream(scriptName);

            if (stream == null)
            {
                var names = asm.GetManifestResourceNames();
                // NOTE: you passed in an invalid name.  
                // Use the above line to determine what tyhe name should be
                // most common is not setting the script file to be an embedded resource
                if (Debugger.IsAttached) Debugger.Break();

                return string.Empty;
            }

            using (var reader = new StreamReader(stream))
            {
                var text = reader.ReadToEnd();

                m_scriptCache.Add(scriptName, text);
            }
        }

        script.Append(m_scriptCache[scriptName]);

        if (encloseInCdata)
        {
            script.Append("//]]>\r\n");
        }

        return script.ToString();
    }
}

修改

为了更清晰,我发布了我的ScriptManager类。要提取脚本文件,我只需将其称为:

var script = ScriptManager.GetScript("Fully.Qualified.Script.js");

您传递的名称是完整的区分大小写的资源名称(异常处理程序通过调用GetManifestResourceNames()获取它们的列表)。

这会将脚本作为字符串提供给您 - 然后您可以将其放入文件中,将其注入页面(这就是我正在做的事情)或者您喜欢的任何内容。

答案 1 :(得分:0)

Assembly myAssembly = // Get your assembly somehow (see below)...
IList<string> resourceNames = myAssembly.GetManifestResourceNames();

这将返回已设置为“Embedded Resource”的所有资源名称的列表。该名称通常是放置该JS文件的任何位置的完全限定名称空间。因此,如果您的项目被调用My.Project,并且您将MyScript.js文件存储在项目名为Resources的文件夹中,则全名为My.Project.Resources.MyScript.js

如果您想使用该JS文件:

Stream stream = myAssembly.GetManifestResourceStream(myResourceName);

myResourceName参数可能是“My.Project.Resources.MyScript.js”。要在该Stream对象中获取该JS文件,您需要将其作为文件写入硬盘驱动器,并将其作为静态文件从您的网站提供,如下所示:

Stream stream = executingAssembly.GetManifestResourceStream(imageResourcePath);
if (stream != null)
{
    string directory = Path.GetDirectoryName("C:/WebApps/MyApp/Scripts/");

    using (Stream file = File.OpenWrite(directory + "MyScript.js"))
    {
        CopyStream(stream, file);
    }

    stream.Dispose();
}

CopyStream方法的代码:

private static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[8 * 1024];
    int len;
    while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, len);
    }
}

您可能希望将所有这些代码都放在Global.asax的Application_Start事件中。您不希望它为每个请求运行


现在获得对大会的参考是另一回事,有很多方法。一种方法是在您的程序集中包含上述所有代码,然后确保从Visual Studio中的主WebApp项目引用该程序集,然后获取对当前正在执行的程序集的引用。

namespace My.Project
{
    public class ResourceLoader
    {
        public static void LoadResources()
        {
            Assembly myAssembly = Assembly.GetExecutingAssembly();

            // rest of code from above (snip)
        }
    }
}

然后从Global.asax中的Application_Start事件中调用ResourceLoader.LoadResources()。

希望这有帮助

答案 2 :(得分:0)

完全正常的例子(我希望):

namespace TestResources.Assembly
{
    public class ResourceLoader
    {
        public static void LoadResources()
        {
            Assembly myAssembly = Assembly.GetExecutingAssembly();

            Stream stream = myAssembly
                .GetManifestResourceStream("TestResources.Assembly.CheckAnswer.js");

            if (stream != null)
            {
                string directory = Path.GetDirectoryName("C:/WebApps/MyApp/Scripts/");

                using (Stream file = File.OpenWrite(directory + "MyScript.js"))
                {
                    CopyStream(stream, file);
                }

               stream.Dispose();
            }
        }

        private static void CopyStream(Stream input, Stream output)
        {
            byte[] buffer = new byte[8 * 1024];
            int len;

            while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                output.Write(buffer, 0, len);
            }
        }
    }
}

一些警告:

  • 将“C:/ WebApps / MyApp /”更改为您的网络应用程序所在的位置,也许可以编写一些代码来动态实现此功能
  • 确保您的webapp根目录中存在/ Scripts文件夹
  • 我认为它会覆盖'MyScript.js'文件(如果它已经存在),但以防你可能想要添加一些代码来检查该文件并将其删除

然后在Global.asax文件中调用此代码:

protected void Application_Start()
{
    ResourceLoader.LoadResources();
}

然后您网站的路径将是/Scripts/MyScript.js,例如:

<head>
    <!-- Rest of head (snip) -->
    <script type="text/javascript" src="/Scripts/MyScript.js"></script>
</head>