【问题标题】:Retrieving embedded resources with special characters检索具有特殊字符的嵌入资源
【发布时间】:2011-04-24 09:22:10
【问题描述】:

我在获取嵌入式资源的流时遇到问题。大多数在线示例显示的路径可以通过将路径的斜杠更改为源的点来直接翻译(MyFolder/MyFile.ext 变为 MyNamespace.MyFolder.MyFile.ext)。但是,当文件夹名称中有一个点并且使用了特殊字符时,手动获取资源名称不起作用。我正在尝试找到一个可以将路径转换为资源名称的函数,因为 Visual Studio 在编译时会重命名它们。

解决方案中的这些名称...

  1. 内容/jQuery.UI-1.8.2/jQuery.UI.css
  2. 脚本/jQuery-1.5.2/jQuery.js
  3. 脚本/jQuery.jPlayer-2.0.0/jQuery.jPlayer.js
  4. 脚本/jQuery.UI-1.8.2/jQuery.UI.js

...在资源中改成这些名字...

  1. Content.jQuery.UI_1._8._2.jQuery.UI.css
  2. Scripts.jQuery_1._5._2.jQuery.js
  3. Scripts.jQuery.jPlayer_2._0._0.jQuery.jPlayer.js
  4. Scripts.jQuery.UI_1._8._12.jQuery.UI.js

斜线被转换为点。但是,当在文件夹名称中使用点时,第一个点显然被视为扩展名,其余点被更改为带有下划线前缀。但是,此逻辑不适用于 jQuery.js 文件,可能是因为“扩展名”是单个数字?这是一个能够翻译我到目前为止遇到的问题的函数,但不适用于 jQuery.js 路径。

    protected String _GetResourceName( String[] zSegments )
    {
        String zResource = String.Empty;

        for ( int i = 0; i < zSegments.Length; i++ )
        {
            if ( i != ( zSegments.Length - 1 ))
            {
                int iPos = zSegments[i].IndexOf( '.' );

                if ( iPos != -1 )
                {
                    zSegments[i] = zSegments[i].Substring( 0, iPos + 1 )
                                 + zSegments[i].Substring( iPos + 1 ).Replace( ".", "._" );
                }
            }

            zResource += zSegments[i].Replace( '/', '.' ).Replace( '-', '_' );
        }

        return String.Concat( _zAssemblyName, zResource );
    }

是否有可以为我更改名称的功能?它是什么?或者我在哪里可以找到所有规则以便我可以编写自己的函数?感谢您提供的任何帮助。

【问题讨论】:

    标签: c# .net resources naming-conventions


    【解决方案1】:

    这是一个很晚的答案......但由于这是谷歌的第一次点击,我将发布我发现的内容!

    您可以简单地强制编译器根据需要命名嵌入的资源;这将从一开始就解决了这个问题......你只需要编辑你的 csproj 文件,如果你想要通配符,你通常会这样做!这是我所做的:

    <EmbeddedResource Include="$(SolutionDir)\somefolder\**">
      <Link>somefolder\%(RecursiveDir)%(Filename)%(Extension)</Link>
      <LogicalName>somefolder:\%(RecursiveDir)%(Filename)%(Extension)</LogicalName>
    </EmbeddedResource>
    

    在这种情况下,我告诉 Visual Studio,我希望将“某个文件夹”中的所有文件作为嵌入式资源导入。此外,我希望它们显示在 VS 解决方案资源管理器中的“某个文件夹”下(这是链接标签)。最后,在编译它们时,我希望它们的名称与它们在我的磁盘上的名称和地址完全相同,只有“somefolder:\”前缀。最后一部分是施展魔法。

    【讨论】:

      【解决方案2】:

      这就是我想出的解决问题的方法。我仍然对更好的方法持开放态度,因为这有点像 hack(但似乎与当前规范是准确的)。该函数需要处理来自 Uri 的段(处理 Web 请求时的 LocalPath)。示例调用如下..

          protected String _GetResourceName( String[] zSegments )
          {
              // Initialize the resource string to return.
              String zResource = String.Empty;
      
              // Initialize the variables for the dot- and find position.
              int iDotPos, iFindPos;
      
              // Loop through the segments of the provided Uri.
              for ( int i = 0; i < zSegments.Length; i++ )
              {
                  // Find the first occurrence of the dot character.
                  iDotPos = zSegments[i].IndexOf( '.' );
      
                  // Check if this segment is a folder segment.
                  if ( i < zSegments.Length - 1 )
                  {
                      // A dash in a folder segment will cause each following dot occurrence to be appended with an underscore.
                      if (( iFindPos = zSegments[i].IndexOf( '-' )) != -1 && iDotPos != -1 )
                      {
                          zSegments[i] = zSegments[i].Substring( 0, iFindPos + 1 ) + zSegments[i].Substring( iFindPos + 1 ).Replace( ".", "._" );
                      }
      
                      // A dash is replaced with an underscore when no underscores are in the name or a dot occurrence is before it.
                      //if (( iFindPos = zSegments[i].IndexOf( '_' )) == -1 || ( iDotPos >= 0 && iDotPos < iFindPos ))
                      {
                          zSegments[i] = zSegments[i].Replace( '-', '_' );
                      }
                  }
      
                  // Each slash is replaced by a dot.
                  zResource += zSegments[i].Replace( '/', '.' );
              }
      
              // Return the assembly name with the resource name.
              return String.Concat( _zAssemblyName, zResource );
          }
      

      示例调用..

          var testResourceName = _GetResourceName( new String[] {
              "/",
              "Scripts/",
              "jQuery.UI-1.8.12/",
              "jQuery-_.UI.js"
          });
      

      【讨论】:

        【解决方案3】:

        罗尔,

        嗯...这是一个 hack,但我想它应该可以工作。只需在每个包含资源的目录中定义一个空的“Marker”类,然后获取其类型的 FullName,从 end 和 wala 中删除类名:这就是您的解码路径。

        string path = (new MarkerClass()).GetType().FullName.Replace(".MarkerClass", "");

        我确信有一种“更好”的方法可以做到这一点......还有更多的代码行;而这个的优点是微软在改变东西时会维护它;-)

        干杯。基思。

        【讨论】:

        • 感谢基思的快速回复。我找不到提到的类,尽管它似乎在“Microsoft.Dss.Services.AssemblyEmbeddedResourceService”中(本地没有)。这通常也意味着 mono 没有它的实现,这是我不能忽视的。也许还有其他方法?
        • 我重申:在每个包含资源的目录中定义一个空的“标记”类。我刚刚编了一个名字“MarkerClass”。我有点谷歌,前提是必须有更好的方法,并想出了这个小宝石:stackoverflow.com/questions/27757/… ...我希望这很有用。
        • 你不能在命名空间中用点定义一个类(这正是我需要的信息,嵌入式资源名称是如何编码的?)。一旦名称正确,我可以根据您的链接参考简单地使用 GetManifestResourceStream。
        • 我不知道你不能在路径中包含点的目录中定义一个类......我猜你被困在试图弄清楚微软的规则,所以你可以编码自己的路径。叹息。
        【解决方案4】:

        这里也有一个迟到的答案,我在自己尝试之前搜索了谷歌,最终我不得不这样做。

        这是我想出的解决方案:

            public string ProcessFolderDash(string path)
            {
                int dotCount = path.Split('/').Length - 1; // Gets the count of slashes
                int dotCountLoop = 1; // Placeholder
        
                string[] absolutepath = path.Split('/');
                for (int i = 0; i < absolutepath.Length; i++)
                {
                    if (dotCountLoop <= dotCount) // check to see if its a file
                    {
                        absolutepath[i] = absolutepath[i].Replace("-", "_");
                    }
        
                    dotCountLoop++;
                }
        
                return String.Join("/", absolutepath);
            }
        

        【讨论】:

          猜你喜欢
          • 2019-09-10
          • 2021-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-19
          • 2017-01-29
          • 2016-10-15
          相关资源
          最近更新 更多