プロジェクト/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();
}
ビルドされたexeを実行すると、次の結果が得られます。
リソースを確認しています...お待ちください... マネージャを取得しました... 指定されたカルチャまたはニュートラル カルチャに適したリソースが見つかりませんでした。コンパイル時に "tmpCC59.tmp.resources" がアセンブリ "Install_testing" に正しく埋め込まれているかリンクされていること、または必要なすべてのサテライト アセンブリがロード可能で完全に署名されていることを確認してください。
誰かがなぜこれが起こっているのか教えてもらえますか? 考えられるすべての異なる文化セットを試してみましたが、まだ何も出てきません。問題は、「埋め込み」または「読み込み」に関連していますか?