none
怎样使用代码将XAML编译为BAML? RRS feed

答案

全部回复

  • 很遗憾的告诉你,官方的回答是不可以这么做的。 

    不过你也可以尝试我曾经试过的方法:


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年3月23日 3:44
    版主
  • 说错了,是把xaml编译成baml。
    2012年3月23日 9:29
  • 好吧, 其实我们需要通过MSBuild 来便以一个包含你XAML文件的project才可以做到, 祥见: http://stackoverflow.com/questions/934945/compile-xaml-into-baml   如果在Runtime的时候,需要我们来生成这个project的msbuild文件 比如一个csproj文件,然后里面增加你所要的程序集引用。 然后调用MSBUILD 编译他. 

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年3月23日 10:01
    版主
  • 能不能使用代码进行编译?
    2012年3月23日 10:17
  • public static void Save(string sourceFilePath, string targetFilePath)
    {
        var path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        Directory.CreateDirectory(path);
        try
        {
            var xamlFile = Path.Combine(path, "input.xaml");
            var projFile = Path.Combine(path, "project.proj");
            //using (var fs = File.Create(xamlFile)) XamlWriter.Save(obj, fs);
            File.Copy(sourceFilePath, xamlFile);
            var engine = new Engine { BinPath = RuntimeEnvironment.GetRuntimeDirectory() };
            var project = engine.CreateNewProject();
            var pgroup = project.AddNewPropertyGroup(false);
            pgroup.AddNewProperty("AssemblyName", "temp");
            pgroup.AddNewProperty("OutputType", "Library");
            pgroup.AddNewProperty("IntermediateOutputPath", ".");
            pgroup.AddNewProperty("MarkupCompilePass1DependsOn", "ResolveReferences");
            var igroup = project.AddNewItemGroup();
            igroup.AddNewItem("Page", "input.xaml");
            igroup.AddNewItem("Reference", "mscorlib");
            igroup.AddNewItem("Reference", "System");
            igroup.AddNewItem("Reference", "System.Core");
            igroup.AddNewItem("Reference", "WindowsBase");
            igroup.AddNewItem("Reference", "PresentationCore");
            igroup.AddNewItem("Reference", "PresentationFramework");
            project.AddNewImport(@"$(MSBuildBinPath)\Microsoft.CSharp.targets", null);
            project.AddNewImport(@"$(MSBuildBinPath)\Microsoft.WinFX.targets", null);
            project.FullFileName = projFile;
            if (!engine.BuildProject(project, "MarkupCompilePass1")) throw new Exception("Baml compilation failed.");
            // attach a logger to the Engine if you need better errors
            File.Copy(Path.Combine(path, "input.baml"), targetFilePath);
        }
        finally
        {
            Directory.Delete(path, true);
        }
    }
    

    我使用了如上代码,但是受到警告:

    警告 1 “Microsoft.Build.BuildEngine.Engine”已过时:“This class has been deprecated. Please use Microsoft.Build.Evaluation.ProjectCollection from the Microsoft.Build assembly instead.” 
    警告 2 “Microsoft.Build.BuildEngine.Engine.BinPath”已过时:“Avoid setting BinPath. If you were simply passing in the .NET Framework location as the BinPath, no other action is necessary. Otherwise, define Toolsets instead in the registry or config file, or by adding elements to the Engine's ToolsetCollection, in order to use a custom BinPath.” 

    如何解决?

    2012年3月23日 11:19
  • 根据警告,你应该用 Microsoft.Build.Evaluation.ProjectCollection 来替代Microsoft.Build.BuildEngine.Engine


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年3月24日 2:58
    版主
  • 如何使用这个类?
    2012年3月24日 4:57
  • 通过 http://msdn.microsoft.com/en-us/library/microsoft.build.evaluation.aspx 名字空间内的各个类型去构建你的MSBuild 项目,然后你可以参考这个帖子的答案来编译 http://social.msdn.microsoft.com/Forums/en/msbuild/thread/ec95c513-f972-45ad-b108-5fcfd27f39bc

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年3月25日 15:03
    版主
  • 已解决,十分感谢。
    2012年3月27日 10:58