none
怪哉! 資料檔怎麼都抓不到? RRS feed

  • 問題

  • 我的專案名稱: H8-VIEW232, 圖檔名為 BlankImage 的 BlankImage.bmp 檔,
    用以下的方式去抓, 總是得到 NULL, 而產生例外. 不知是那裡有錯?

    (1)
       Assembly myAssem = Assembly.GetEntryAssembly();
       ResourceManager rm = new ResourceManager("H8-VIEW232.BlankImage", myAssem);
       Image img = (Image)(rm.GetObject("H8-VIEW232.BlankImage"));

    (2)
        Assembly _assembly = Assembly.GetExecutingAssembly();
        Stream _imageStream = _assembly.GetManifestResourceStream("H8-VIEW232.BlankImage.bmp");
        Image img = new Bitmap(_imageStream);

    其中的 BaseName 有試過 : "H8-VIEW232", "H8-VIEW232.Properties", "H8-VIEW232.Properties.Resources" ,
    "H8-VIEW232.Properties", "H8-VIEW232.Properties.Resources" 等等.

    檔案的屬性如下:
    自定工具 : (空白)
    自定工具命名空間 : (空白)
    完整路徑 : F:\H8-VIEW232\Resources\ BlankImage.bmp
    建置動作 : 內崁資源
    複置到輸出目錄: 不要複置
    檔名 : BlankImage.bmp

    Resources.Designer.cs 如下 :
    namespace H8_VIEW232.Properties {
        using System;
            
        /// <summary>
        ///   用於查詢當地語系化字串等的強型別資源類別
        /// </summary>
        // 這個類別是自動產生的,是利用 StronglyTypedResourceBuilder
        // 類別透過 ResGen 或 Visual Studio 這類工具。
        // 若要加入或移除成員,請編輯您的 .ResX 檔,然後重新執行 ResGen
        // (利用 /str 選項),或重建您的 VS 專案。
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
        internal class Resources {
           
            private static global::System.Resources.ResourceManager resourceMan;
           
            private static global::System.Globalization.CultureInfo resourceCulture;
           
            [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
            internal Resources() {
            }
           
            /// <summary>
            ///   傳回這個類別使用的快取的 ResourceManager 執行個體。
            /// </summary>
            [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
            internal static global::System.Resources.ResourceManager ResourceManager {
                get {
                    if (object.ReferenceEquals(resourceMan, null)) {
                        global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("H8_VIEW232.Properties.Resources", typeof(Resources).Assembly);
                        resourceMan = temp;
                    }
                    return resourceMan;
                }
            }
           
            /// <summary>
            ///   覆寫目前執行緒的 CurrentUICulture 屬性,對象是所有
            ///   使用這個強型別資源類別的資源查閱。
            /// </summary>
            [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
            internal static global::System.Globalization.CultureInfo Culture {
                get {
                    return resourceCulture;
                }
                set {
                    resourceCulture = value;
                }
            }
           
            internal static System.Drawing.Bitmap BlankImage {
                get {
                    object obj = ResourceManager.GetObject("BlankImage", resourceCulture);
                    return ((System.Drawing.Bitmap)(obj));
                }
            }
        }
    }


    MSDN 不知看了幾遍, 還是不行, 真是令人髮指, 有誰能幫忙指出錯誤呢?

    先謝了 !!!

    2009年12月4日 上午 04:54

解答

所有回覆

  • 參考看看這篇的範例

    [C#.NET][VB.NET] 如何取得資源檔 (ResourceManager) 的 資料 / 圖片
    http://www.dotblogs.com.tw/yc421206/archive/2009/11/04/11398.aspx
    • 已標示為解答 H.C.Lin 2009年12月4日 上午 07:02
    2009年12月4日 上午 05:25
    版主
  • 這個範例說明的非常清楚.
    我實際操作, 用 Properties.Resources.MyPic 的方法, 確實無誤.
    但是用    
       ResourceManager rm = new ResourceManager("H8-VIEW232.Properties.Resources", Assembly.GetEntryAssembly());
       Image img = (Image)rm.GetObject("MyPic");
    還是不行, 真是奇了.
    不過, 至少已經有方法可用, 不再卡住了. 有空,  我再研究研究.
    謝謝您了.
    2009年12月4日 上午 07:09
  • Hi,

    改成
    ResourceManager rm = new ResourceManager("H8-VIEW232.Properties.Resources", Assembly. GetExecutingAssembly());
    Image img = (Image)rm.GetObject("BlankImage");
    呢?

    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2009年12月4日 上午 08:23
  • Hi ~ 您好

    用您所建議的 code :
    ResourceManager rm = new ResourceManager("H8-VIEW232.Properties.Resources", Assembly. GetExecutingAssembly());
    Image img = (Image)rm.GetObject("BlankImage");  
    執行後, 第二行, 一定會產生例外 (Exception). 內容如下 :
    "
    ....
    找不到任何適用特定文化特性或中性文化特性的資源。
    請確定您已在編譯時期正確地將 "H8-VIEW232.Properties.Resources.resources" 嵌入或連結至組件 "H8-VIEW232" 中,
    或所有需要的附屬組件均為可載入且已完整簽署。
    "

    改用
    ResourceManager rm = new ResourceManager("H8-VIEW232.Properties", Assembly. GetExecutingAssembly());
    Image img = (Image)rm.GetObject("BlankImage");  
    執行後, 第二行, 例外 (Exception) 照常出現.

    真是要命.

    上週 我改用  Properties.Resources.MyPic 後, 就可以正常存取圖檔, 程式順利完成.
    但是 , 今天早上我用 vs2008 所附的 dotfuscator 打包這支程式後, 一執行它, 
    例外 (Exception) 又來了. 

    唉~~~ 
     
    無論如何, 謝謝您的回覆.


    2009年12月7日 上午 07:07
  • Hi,

    所以你的資源名稱是MyPic?

    是的話改用下面這樣呢?
    ResourceManager rm = new ResourceManager("H8-VIEW232.Properties.Resources", Assembly. GetExecutingAssembly());
    Image img = (Image)rm.GetObject("MyPic");   

    如果是MyPic,那你上面的Code為何是BlankImage?
      internal static System.Drawing.Bitmap BlankImage {
                get {
                    object obj = ResourceManager.GetObject("BlankImage", resourceCulture);
                    return ((System.Drawing.Bitmap)(obj));
                }

    順帶一提,這篇KB你也可以參考一下

    當您嘗試存取當地語系化的資源時,發生一個 System.Resources.MissingManifestResourceException 例外狀況


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2009年12月7日 上午 07:16
  • Sorry !

    "MyPic" 這是個上禮拜在 Try 時, 重新建立同一張圖的新名, 剛剛在打字時, copy 下來, 忘記改回 "BlankImage"

    我的測試程式碼如下:
       System.Drawing.Graphics graphics = this.CreateGraphics();
       
       Image img1 = Properties.Resources.BlankImage; 
       graphics.DrawImage(img1, 100, 40);

       //ResourceManager rm = new ResourceManager("H8-VIEW232.Properties.Resources", Assembly.GetEntryAssembly());
       //Image img2 = (Image)rm.GetObject("BlankImage");
       //graphics.DrawImage(img2, 150, 40);

    放在ㄧ起,  測試時, mark 掉無關的地方, 就算沒 mark掉, 也沒關係, 因為圖的坐標沒有重疊.
    這樣可以確定, 加入資源檔的的圖檔沒問題.

    您建議的網址, 我會去看看的.
    謝謝.

    2009年12月7日 上午 08:08
  • 終於找到原因了.

    原因如下 :
    (1)
    Q:
      ResourceManager rm = new ResourceManager("H8-VIEW232.Properties", Assembly. GetExecutingAssembly());
      Image img = (Image)rm.GetObject("BlankImage");  
      會產生例外 (Exception).
    A:
      我的專案命名為 "H8-VIEW232", 但是 , C# 的命名空間名稱規則並不允許 '-' 的字元, 所以, IDE 自動改為 "H8_ VIEW232",
      因此, 在指定 BaseName時, 若用 "H8-VIEW232.Properties", 永遠找不到這個空間的資源, 因而就產生例外(Exception).
      改為
      ResourceManager rm = new ResourceManager("H8_VIEW232.Properties", Assembly. GetExecutingAssembly());
      Image img = (Image)rm.GetObject("BlankImage");  
      即可

    (2)
    Q:
      正常程式 用 vs2008 所附的 dotfuscator 打包這支程式後, 一執行它, 例外 (Exception) 產生. 
    A:
      程式內有叫用崁入式資源 其 NameSpace 的引用, 如同 Class 繼承階層的引用 , 例如: "H8_VIEW232.Properties.Resources.BlankImage" 之中, 前面的"H8_VIEW232.Properties" 是 NameSpace 的引用, 而 後面的
    "Resources.BlankImage" 是 Class 繼承階層的引用, 然而, dotfuscator 則會把"H8_VIEW232.Properties.Resources" 當作Class 繼承階層 而加以 Rename,  因而, 打包後的程式, 會產生例外 (Exception) .
    我試過 dotfuscator community edition (V4.0),  也試過 dotfuscator profession edition (V4.2) 皆如此, 要使用 dotfuscator 的朋友, 要注意這一點.

    感謝各路豪傑的幫忙. 把這些問題寫出來, 是希望冤望路我走一次就好, 其他人繞過去不要走, 就這樣子而已.




    2009年12月8日 上午 08:10