Visual studio 如何使用Roslyn Workspace预编译项目

Visual studio 如何使用Roslyn Workspace预编译项目,visual-studio,visual-studio-2015,roslyn-code-analysis,microsoft.codeanalysis,Visual Studio,Visual Studio 2015,Roslyn Code Analysis,Microsoft.codeanalysis,我需要编译一个启用预编译的ASP.NETWeb应用程序(web窗体和MVC)。我正在使用Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace打开项目并发出项目级程序集。我已经确定RazorGenerator可以用于预编译,但这会给我的解决方案增加额外的复杂性,有没有一种方法可以简单地使用Roslyn Workspace来实现这一点?我提出了以下代码来生成预编译的构建,但是,我正在寻找一种不需要很多文件级操作的更健壮的方法 static void

我需要编译一个启用预编译的ASP.NETWeb应用程序(web窗体和MVC)。我正在使用Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace打开项目并发出项目级程序集。我已经确定RazorGenerator可以用于预编译,但这会给我的解决方案增加额外的复杂性,有没有一种方法可以简单地使用Roslyn Workspace来实现这一点?

我提出了以下代码来生成预编译的构建,但是,我正在寻找一种不需要很多文件级操作的更健壮的方法

    static void Main(string[] args)
    {
        //MVC APP
        string projectFileName = @"C:\MVCWebApplication\MVCWebApplication\MVCWebApplication.csproj";
        string appName = "MVCWebApplication";

        //ASP.NET Web Forma App
        //string projectFileName = @"C:\AapApp\WebGoat\WebGoat.NET.csproj";
        //string appName = "WebGoat.NET";

        //Build Artifacts will be drop to this location
        string publishDrop = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

        //aspnet compiler will drop precompiled artifacts to this location
        string precompiledDrop = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

        //Publishing the extension without precompile
        var pc = new ProjectCollection();
        var globalProperty = new Dictionary<string, string>();
        globalProperty.Add("Configuration", "Debug");
        globalProperty.Add("Platform", "x86");
        globalProperty.Add("OutputPath", publishDrop);
        globalProperty.Add("WebPublishMethod", "FileSystem");
        globalProperty.Add("EnableUpdateable", "false");
        globalProperty.Add("DebugSymbols", "true");
        globalProperty.Add("VisualStudioVersion", "14.0");//TODO: Get from IDE

        var buidlRequest = new BuildRequestData(projectFileName, globalProperty, null, new string[] { "Build" }, null);
        var buildResult = BuildManager.DefaultBuildManager.Build(new BuildParameters(pc), buidlRequest);

        //If build errors; then trow
        if (buildResult.Exception != null)
        {
            throw buildResult.Exception;
        }

        //Rslyn folder not getting created in required location in VS 2015 MVC app template
        //https://stackoverflow.com/questions/32780315/could-not-find-a-part-of-the-path-bin-roslyn-csc-exe
        //Moving it to proper location manually
        string publish = Path.Combine(publishDrop, "_PublishedWebsites", appName);
        if (!Directory.Exists(Path.Combine(publish, "bin", "Roslyn")) &&
            Directory.Exists(Path.Combine(publishDrop, "Roslyn")))
        {
            Directory.Move(Path.Combine(publishDrop, "Roslyn"), Path.Combine(publish, "bin", "Roslyn"));
        }

        //Executing aspnet compiler to get the final output
        using (var cmd = new Process())
        {                
            cmd.StartInfo.FileName = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe";
            cmd.StartInfo.Arguments = @"-v / -p " + publishDrop + @"\_PublishedWebsites\" + appName + " " + precompiledDrop;
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.UseShellExecute = false;
            cmd.Start();

            cmd.StandardInput.Flush();
            cmd.StandardInput.Close();
            cmd.WaitForExit();
            Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            //TODO: Check result for any precompilation errors,
        }

        //Cleanup files in final precopiled artifact drop
        if (Directory.Exists(Path.Combine(precompiledDrop, "bin", "Roslyn")))
        {
            Directory.Delete(Path.Combine(precompiledDrop, "bin", "Roslyn"), true);
        }

        Console.ReadKey();        
    }
static void Main(字符串[]args)
{
//MVC应用程序
string projectFileName=@“C:\MVCWebApplication\MVCWebApplication\MVCWebApplication.csproj”;
字符串appName=“MVCWebApplication”;
//ASP.NET Web Forma应用程序
//字符串projectFileName=@“C:\AapApp\WebGoat\WebGoat.NET.csproj”;
//字符串appName=“WebGoat.NET”;
//生成工件将被放置到此位置
string publishDrop=Path.Combine(Path.GetTempPath(),Path.GetRandomFileName());
//aspnet编译器将把预编译的工件放到这个位置
string precompiledDrop=Path.Combine(Path.GetTempPath(),Path.GetRandomFileName());
//在不预编译的情况下发布扩展
var pc=新项目集合();
var globalProperty=新字典();
添加(“配置”、“调试”);
添加(“平台”、“x86”);
添加(“OutputPath”,publishDrop);
添加(“WebPublishMethod”、“文件系统”);
globalProperty.Add(“EnableUpdateable”、“false”);
添加(“调试符号”、“真”);
globalProperty.Add(“VisualStudioVersion”,“14.0”);//TODO:从IDE获取
var buidlRequest=newbuildrequestdata(projectFileName,globalProperty,null,新字符串[]{“Build”},null);
var buildResult=BuildManager.DefaultBuildManager.Build(新的BuildParameters(pc),buildRequest);
//如果生成错误,则trow
if(buildResult.Exception!=null)
{
抛出buildResult.Exception;
}
//未在VS 2015 MVC应用程序模板中的所需位置创建Rslyn文件夹
//https://stackoverflow.com/questions/32780315/could-not-find-a-part-of-the-path-bin-roslyn-csc-exe
//手动将其移动到适当的位置
字符串publish=Path.Combine(publishDrop,“\u PublishedWebsites”,appName);
如果(!Directory.Exists)(Path.Combine(publish,“bin”,“Roslyn”))&&
目录.Exists(Path.Combine(publishDrop,“Roslyn”))
{
Directory.Move(Path.Combine(publishDrop,“Roslyn”)、Path.Combine(publish,“bin”,“Roslyn”);
}
//执行aspnet编译器以获得最终输出
使用(var cmd=new Process())
{                
cmd.StartInfo.FileName=@“C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet\u compiler.exe”;
cmd.StartInfo.Arguments=@“-v/-p”+publishDrop+@“\\\ U PublishedWebsites\\”+appName+“”+precompiledDrop;
cmd.StartInfo.RedirectStandardInput=true;
cmd.StartInfo.RedirectStandardOutput=true;
cmd.StartInfo.CreateNoWindow=true;
cmd.StartInfo.UseShellExecute=false;
cmd.Start();
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
//TODO:检查结果是否存在任何预编译错误,
}
//清理最终预编译工件放置中的文件
if(Directory.Exists(Path.Combine(预编译的drop,“bin”,“Roslyn”)))
{
Directory.Delete(Path.Combine(precompiledDrop,“bin”,“Roslyn”),true);
}
Console.ReadKey();
}

MSBuildWorkspace是Roslyn工作区。我怀疑RazorGenerator正在为项目中的内容生成额外的源代码,因此从MSBuildWorkspace发出编译不太可能工作,因为它不会包含所有源代码。@MattWarren:是的Matt Warren,我必须使用MSBuild将web应用发布到一个文件夹中,并使用aspnet_comiler.exe预编译发布的工件(请参考我的答案)。此方法生成所需的二进制文件,但是我正在为此寻找一段更健壮的代码,可能会避免MSBuild和aspnet_compiler.exe。此代码工作正常,并发出预期的输出,但有更健壮的方法吗?