2015-05-29 76 views
5

我最近實現了下面的代碼,以編程方式構建一個項目/ exe。在這個EXE版本中,我想將一堆「實際文件」作爲流存儲在資源中。以編程方式加載嵌入的資源文件

這裏就是我如何添加文件到資源文件(單數),然後嵌入該資源文件到編譯器參數:

 List<string> UserFiles = new List<string>(); 
     UserFiles.AddRange(Helpers.GetFilesInFolder(this.txt_Publish_Folder.Text)); 

     string folder = this.txt_Package_Location.Text; 
     folder = folder + "\\Package_" + DateTime.Now.ToLongTimeString().Replace(":", "_").Replace(".", "_"); 
     Directory.CreateDirectory(folder); 

     CompilerParameters parameters = new CompilerParameters(); 
     parameters.GenerateExecutable = true; 
     parameters.IncludeDebugInformation = true; 
     parameters.GenerateInMemory = false; 
     parameters.WarningLevel = 3; 
     parameters.CompilerOptions = "/optimize"; 
     parameters.OutputAssembly = folder + "\\Install_" + this.txt_AppName.Text + ".exe"; 
     parameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll"); 
     parameters.ReferencedAssemblies.Add("System.dll"); 
     parameters.ReferencedAssemblies.Add("System.Core.dll"); 
     parameters.ReferencedAssemblies.Add("System.Data.dll"); 
     parameters.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll"); 
     parameters.ReferencedAssemblies.Add("System.Xml.dll"); 
     parameters.ReferencedAssemblies.Add("System.Xml.Linq.dll"); 

     CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp"); 
     if (codeProvider.Supports(GeneratorSupport.Resources)) 
     { 
      string temp = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); 
      //create temp file first, because we want to append to it so as to have a single resource file with multiple stream entries... 
      File.WriteAllText(temp, null); 
      for (int i = 0; i < UserFiles.Count; i++) 
      { 
       byte[] FileBytes = File.ReadAllBytes(UserFiles[i]); 

       using (FileStream stream = new FileStream(temp, FileMode.Append)) 
       { 
        using (ResourceWriter writer = new ResourceWriter(stream)) 
        { 
         writer.AddResource(Path.GetFileName(UserFiles[i]), FileBytes); 
        } 
       } 
      } 
      parameters.EmbeddedResources.Add(temp); 
     } 

     CompilerResults res = codeProvider.CompileAssemblyFromFile(parameters, @"C:\HIDDENPATH\Program.cs"); 

這個偉大的工程,不產生任何錯誤,並我實際上可以通過下面的代碼在我構建的控制檯應用程序(以上稱爲Prorgam.cs)中獲取嵌入式資源文件。但是我遇到的問題是「加載」這個資源文件到應用程序組件/獲取它的值了莫名其妙......這裏的代碼,我到目前爲止做:

static void Main(string[] args) 
    { 
     Console.WriteLine("Checking for resources... please wait..."); 

     Assembly thisExe; 
     thisExe = Assembly.GetExecutingAssembly(); 
     List<string> resources = thisExe.GetManifestResourceNames().ToList(); 

     if(resources.Count >= 1) 
     { 
      try 
      { 
       string baseName = resources[0]; 
       ResourceManager mgr = new ResourceManager(baseName, thisExe); 
       Console.WriteLine("retrieved manager..."); 
       Console.ReadLine(); 
       ResourceSet set = mgr.GetResourceSet(Thread.CurrentThread.CurrentCulture, true, true); 
       int count = set.Cast<object>().Count(); 
       Console.WriteLine("Found [" + count.ToString() + "] embedded resources. Would you like to enumerate them?"); 
       ConsoleKeyInfo input = Console.ReadKey(); 
       if (input.Key == ConsoleKey.Y) 
       { 
        // Build the string of resources. 
        foreach (string resource in resources) 
         Console.WriteLine(resource); 
       } 

      } 
      catch (Exception ex) 
      { 
       Console.Write(ex.Message); 
       Console.ReadLine(); 
      } 
     } 

     Console.ReadLine(); 
    } 

每當我運行內置我得到以下結果:

 

Checking for resources... please wait... 
retrieved manager... 

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "tmpCC59.tmp.resources" was correctly embedded or linked into assembly "Install_testing" at compile time, or that all the satellite assemblies required are loadable and fully signed. 

有人可以告訴我爲什麼這是發生?我已經嘗試過所有我能想到的不同文化背景,但仍然沒有出現。問題與我如何「嵌入」或我如何「加載」有關?

回答

0

好的人,所以這就是我最終結果,這實際上解決了我所有的問題。

  1. ,而不是試圖增加「資源項」成一個單一的「資源文件」,我現在從源文件中添加的所有文件作爲自己的資源,直接(不知道爲什麼我想製作原來的臨時副本,並使用流是必要的,但它不是)這樣的:當談到時間來提取的,而不是試圖加載一個「套」,從單一的實際文件,

     for (int i = 0; i < WebAppFiles.Count; i++) 
         { 
          parameters.EmbeddedResources.Add(WebAppFiles[i]); 
         } 
    
  2. 然後, 「資源文件」,我只是從每個嵌入式資源提取數據,如下所示:

       for (int i = 0; i < resources.Count; i++) 
           { 
            Console.WriteLine("Extracting file: " + resources[i] + "..."); 
            Stream stream = thisExe.GetManifestResourceStream(resources[i]); 
            byte[] bytes = new byte[(int)stream.Length]; 
            stream.Read(bytes, 0, bytes.Length); 
            File.WriteAllBytes(dir + resources[i], bytes); 
           } 
    

這種新的方式基本上意味着你告訴編譯器,「這些文件是必要的exe文件和嵌入」,所以當你調用「構建」命令,它實際上做所有的工作爲您和讀取字節數組中的文件並將其嵌入到可執行文件中。

然後,另一方面,您只需告訴程序要使用自己的文件名將嵌入式資源另存爲文件。

希望這可以幫助別人試圖做到這一點......因爲這類問題的其他所有帖子都有一些複雜的答案,這些答案要麼不完整(例如:如何嵌入,但不能檢索)實際上工作。

相關問題