我最近实现了以下代码,以便以编程方式构建项目/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”中,或者所有所需的附属程序集都是可加载的并且完全签名。
有人可以告诉我为什么会这样吗?我已经尝试了我能想到的所有不同的文化集,但仍然没有任何结果。问题与我如何“嵌入”或我如何“加载”有关吗?