Получение встроенных ресурсов с помощью специальных символов - PullRequest
9 голосов
/ 24 апреля 2011

У меня проблема с получением потоков для встроенных ресурсов. В большинстве примеров в Интернете показаны пути, которые можно напрямую перевести, изменив косую черту пути на точку для источника (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 );
    }

Есть ли функция, которая может изменить имена для меня? Что это? Или где я могу найти все правила, чтобы написать свою собственную функцию? Спасибо за любую помощь, которую вы можете оказать.

Ответы [ 4 ]

5 голосов
/ 25 июня 2015

Это довольно поздний ответ ... Но так как это был первый хит в Google, я опубликую то, что нашел!

Вы можете просто заставить компилятор назвать встроенный ресурс какты хочешь это;Это как бы решает эту проблему с самого начала ... Вам просто нужно отредактировать файл csproj, что вы обычно делаете, если хотите, чтобы в нем были символы подстановки!вот что я сделал:

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

В этом случае я говорю Visual Studio, что я хочу, чтобы все файлы в «некоторой папке» были импортированы как встроенные ресурсы.Также я хочу, чтобы они отображались в «некоторой папке» в VS Solution Explorer (это тег ссылки).И, наконец, при их компиляции я хочу, чтобы они были названы точно с тем же именем и адресом, что и на моем диске, с префиксом «somefolder: \».Последняя часть делает магию.

4 голосов
/ 24 апреля 2011

Это то, что я придумал, чтобы решить проблему.Я все еще открыт для лучших методов, так как это немного хакерство (но, похоже, точное с текущими спецификациями).Функция ожидает сегмент от Uri для обработки (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"
    });
1 голос
/ 24 апреля 2011

Roel,

Хммм ... Это взломать, но я думаю, это должно работать.Просто определите пустой класс «Marker» в каждом каталоге, который содержит ресурсы, затем получите полное имя его типа, удалите имя класса из end и wala: это ваш декодированный путь.

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

Я уверен, что есть "лучший" способ сделать это ... с ОЧЕНЬ большим количеством строк кода;и этот имеет то преимущество, что Microsoft поддерживает его, когда они что-то меняют; -)

Приветствия.Кит.

0 голосов
/ 13 августа 2015

Здесь также поздний ответ, я гуглил, прежде чем попытался сделать это самостоятельно, и мне в конце концов пришлось.

Вот решение, которое я придумал:

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