检索具有特殊字符的嵌入资源

时间:2011-04-24 09:22:11

标签: c# .net resources naming-conventions

我在获取嵌入式资源的流方面遇到了问题。大多数在线示例显示可以通过将路径的斜线更改为源的点(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
  5. ...在资源中更改为这些名称......

    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
    5. 斜线转换为点。但是,当在文件夹名称中使用点时,第一个点显然被视为扩展名,其余的点被更改为以下划线为前缀。但是,这个逻辑不适用于jQuery.js文件,可能是因为'extension'是一个数字?这是一个能够翻译我迄今为止遇到的问题的函数,但是在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 );
          }
      

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

4 个答案:

答案 0 :(得分:5)

这是一个非常晚的答案...但由于这是谷歌的第一次打击,我会发布我发现的内容!

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

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

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

答案 1 :(得分:4)

这就是我想出来解决问题的方法。我仍然愿意接受更好的方法,因为这有点像黑客攻击(但对于当前的规范来说似乎是准确的)。该函数期望来自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"
    });

答案 2 :(得分:1)

罗埃尔,

嗯...这是一个黑客,但我想它应该有效。只需在每个包含资源的目录中定义一个空的“Marker”类,然后获取它的类型的FullName,从end和wala中删除类名:这是你的解码路径。

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

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

干杯。基思。

答案 3 :(得分:0)

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

以下是我提出的解决方案:

    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);
    }