3

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

4

1 回答 1

1

我想出了以下代码来生成预编译的构建,但是寻找一种没有很多文件级操作的更健壮的方法。

    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();        
    }
于 2017-08-30T05:32:59.880 回答