I need to compile an ASP.Net web applications (Web Forms and MVC) with pre-compile enabled. I'm using Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace to open the project and emit project level assemblies. I have identified RazorGenerator can be used to pre-compile but this will add additional complexity to my solution, Is there a way to so this simply using Roslyn Workspace?
Asked
Active
Viewed 733 times
3

Zhanglong Wu - MSFT
- 1,652
- 1
- 7
- 8

Bandara
- 780
- 8
- 29
-
MSBuildWorkspace is a Roslyn Workspace. I suspect though that RazorGenerator is generating additional source code to what is in your project, so emitting the compilation from the MSBuildWorkspace is unlikely to work, as it won't have all the source. – Matt Warren Aug 29 '17 at 20:57
-
@MattWarren: Yes Matt Warren, I had to publish the web app to a folder using MSBuild and use aspnet_comiler.exe to precompile the published artifacts (Please refer my answer). This method generates required binaries, however I'm looking for a more robust piece of code for this, perhaps avoiding MSBuild and aspnet_compiler.exe – Bandara Aug 30 '17 at 05:30
1 Answers
1
I have come up with following piece of code to generate the precompiled build, however looking for a more robust way without many file level operations.
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();
}

Bandara
- 780
- 8
- 29
-
This code works fine and emits expected ourput, but is there a more robust way of doing this? – Bandara Oct 19 '17 at 08:37