2011-04-24 28 views
7

我在爲嵌入式資源獲取流時遇到了問題。大多數在線示例顯示可通過將路徑的斜槓更改爲源點(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); 
    } 

有沒有可以改變我的名字的函數?它是什麼?或者我在哪裏可以找到所有規則,以便我可以編寫自己的功能?感謝您可能提供的任何幫助。

回答

2

這就是我想出來解決這個問題。我仍然開放更好的方法,因爲這有點破解(但對於當前的規範來說似乎是準確的)。該函數需要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" 
    }); 
1

羅埃爾,

嗯......這是一個黑客,但我想它應該工作。只需在每個包含資源的目錄中定義一個空的「標記」類,然後獲取其類型的FullName,從末尾刪除類名,然後輸入你的解碼路徑。

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

我敢肯定有一個「更好」的方式來做到這一點...用代碼很多多行;而且這個優點是微軟在改變內容時可以保留它;-)

乾杯。基思。

+0

感謝您的快速反應基思。我無法找到提到的類,儘管它看起來是在「Microsoft.Dss.Services.AssemblyEmbeddedResourceService」(本地沒有)。這通常也意味着mono沒有實現它,這是我不能忽視的。也許還有其他方法? – 2011-04-24 09:57:57

+0

我重申:在每個包含資源的目錄中定義一個空的「標記」類。我剛寫下「MarkerClass」這個名字。我有一個谷歌,前提是有一個更好的方法,並提出了這個小寶石:http://stackoverflow.com/questions/27757/how-can-i-discover-the-嵌入式資源的路徑......我希望這很有用。 – corlettk 2011-04-24 10:02:14

+0

你不能在帶點的名字空間中定義一個類(這正是我需要的信息,嵌入的資源名稱是如何編碼的?)。一旦名字正確,我可以根據你的鏈接引用簡單地使用GetManifestResourceStream。 – 2011-04-24 10:25:11

2

這是一個很晚的答案...但是因爲這是谷歌的第一次打擊,我會發布我發現的!

您可以簡單地強制編譯器根據需要命名嵌入的資源;從一開始就會解決這個問題......你只需要編輯你的csproj文件,如果你需要通配符的話,你通常會這麼做!這裏是我做過什麼:

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

在這種情況下,我告訴Visual Studio中,我想在「某個文件夾」中的所有文件導入爲嵌入的資源。此外,我希望它們在VS解決方案資源管理器中的「某個文件夾」下顯示(這是鏈接標記)。最後,編譯它們時,我希望它們的命名與我的磁盤上的名稱和地址完全相同,只有「somefolder:\」前綴。最後一部分是在做魔術。

0

這裏也有一個遲到的答案,在我嘗試使用之前,我搜索了一個最近的答案,最終我不得不這樣做。

這是我想出瞭解決方案:

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