使用CSharpCodeDomProvider使用资源文件进行编译

时间:2014-03-03 14:37:30

标签: c# .net csharpcodeprovider

我正在尝试构建一个程序,它将使用xml文件作为资源编译一个.cs。我有以下编译代码:

private void Builder(bool run)
{
    CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp");
    string output = "Output.exe";
    string inputXml = "Input.xml";
    string xml = File.ReadAllText(inputXml);
    string inputCS = Properties.Resources.Program;
    IResourceWriter writer = new ResourceWriter("temp.resources");
    writer.AddResource("Story", xml);
    writer.Close();
    CompilerParameters parameters = new CompilerParameters();
    //Make sure we generate an EXE, not a DLL
    parameters.GenerateExecutable = true;
    parameters.OutputAssembly = output;
    parameters.GenerateInMemory = false;
    parameters.ReferencedAssemblies.Add("System.dll");
    parameters.ReferencedAssemblies.Add("mscorlib.dll");
    parameters.ReferencedAssemblies.Add("System.Xml.dll");
    parameters.EmbeddedResources.Add("temp.resources");
    CompilerResults results = compiler.CompileAssemblyFromSource(parameters, inputCS);
    if (run)
    {
        Process.Start(output);
    }
}

但它有编译错误,并说Properties不是Properties.Resources.Story的有效参考:

要编译的cs文件中的代码

static bool LoadData()
{
    bool result = true;
    Program.doc = new XmlDocument();
    doc.LoadXml(Properties.Resources.Story);
    return result;
}

更新:这是特定错误:

  

c:\ Users \ Nick \ AppData \ Local \ Temp \ zk14fqrm.0.cs(38,25):错误CS0103:当前上下文中不存在名称“属性”

那么需要改变以解决这个问题呢?

2 个答案:

答案 0 :(得分:3)

    writer.AddResource("Story", xml);

这不符合你的期望。嵌入资源比批次更多。 IDE和msbuild.exe完成了大量工作,使Properties.Resources代码在运行时工作。粗略的步骤:

  • Project + Properties,Resource选项卡,Add Resource生成.xml文件。大概是一个与您在代码中使用的非常相似的那个。
  • 这也是自动生成代码,您可以通过打开Properties + Resources.resx + Resources.Designer.cs文件来查看它。这个文件声明了Properties.Resources类。在您的代码中没有完成此步骤,这解释了编译错误
  • 在构建时,.resx文件从XML转换为更紧凑且适合嵌入到程序集内的格式。这是由Resgen.exe构建工具完成的。它将.xml文件转换为.resources文件。请注意你是如何做错的,你正在将xml写入.resources文件而不是Resgen.exe输出。

使用CodeDom重现所有这一切确实非常痛苦,尤其是自动生成的代码步骤。实际方法是将资源保留在文件中,而不是尝试嵌入它们,嵌入单个资源并使用Assembly.GetManifestResourceStream()在运行时检索并显式使用ResourceManager,如Resources.Designer.cs文件中所示。

答案 1 :(得分:2)

是的,这是可以预料的。 Properties.Resources类由visual studio代码生成器自动生成。它不是C#编译器的一个特性。

因此,您仍需要添加相应的Resources.Designer.cs文件,,以便在构建过程中调用代码生成器,并将自动生成的文件添加到{{ 1}}要编译的文件。