CompilerResults CompileAssemblyFromFileBatchImpl(CompilerParameters options, string[] fileNames)
{
//System.Diagnostics.Debug.Assert(false);
CompilerResults retval = new CompilerResults(new TempFileCollection());
if (Environment.Version.Major < 2)
{
throw new ApplicationException("C++/CLI scripts are only supported on .NET 2.0 and higher. Please ensure the script engine is running under the appropriate version of CLR.");
}
string outputName = Path.GetFileNameWithoutExtension(options.OutputAssembly);
string tempDir = Path.Combine(Path.GetTempPath(), "CSSCRIPT\\CPP\\" + System.Guid.NewGuid().ToString());
string tempProj = Path.Combine(tempDir, outputName + ".vcxproj");
string outputFile = Path.Combine(tempDir, "Debug\\"+outputName + (options.GenerateExecutable ? ".exe" : ".dll"));
if (Directory.Exists(tempDir))
Directory.Delete(tempDir, true);
Directory.CreateDirectory(tempDir);
using (StreamReader sr = new StreamReader(ProjTemplateFile))
using (StreamWriter sw = new StreamWriter(tempProj))
{
string content = sr.ReadToEnd();
content = content.Replace("$NAME$", outputName);
//content = content.Replace("$TEMP_DIR$", tempDir);
content = content.Replace("$INTER_DIR$", tempDir);
content = content.Replace("$PREPR_DEBUG$", options.IncludeDebugInformation ? "_DEBUG" : "");
content = content.Replace("$DEBUG$", options.IncludeDebugInformation ? "true" : "false");
if (options.GenerateExecutable) //exe
{
//if (options.CompilerOptions != null && options.CompilerOptions.IndexOf("/target:winexe") != -1) //WinForm
//{
// content = content.Replace("$MANAGED_EXT$", "2");
// content = content.Replace("$LINK_WINFORM$", "SubSystem=\"2\"\r\nEntryPointSymbol=\"main\"");
//}
//else
//{
// content = content.Replace("$MANAGED_EXT$", "1"); //console
// content = content.Replace("$LINK_WINFORM$", "");
//}
content = content.Replace("$TYPE$", "Application");
}
else //dll
{
//content = content.Replace("$MANAGED_EXT$", "1");
//content = content.Replace("$LINK_WINFORM$", "");
content = content.Replace("$TYPE$", "DynamicLibrary");
}
string template = @"<Reference Include=""{0}"">
<HintPath>""{1}""</HintPath>
</Reference>"+"\n";
string references = "";
foreach (string file in options.ReferencedAssemblies)
references += string.Format(template, Path.GetFileNameWithoutExtension(file), file);
content = content.Replace("$REFERENCES$", references);
template = "<ClCompile Include=\"{0}\" />\n";
string sources = "";
foreach (string file in fileNames)
sources += string.Format(template, file);
content = content.Replace("$SOURCE_FILES$", sources);
sw.Write(content);
}
string compileLog = "";
//Stopwatch sw1 = new Stopwatch();
//sw1.Start();
string msbuild = Path.Combine(Path.GetDirectoryName("".GetType().Assembly.Location), "MSBuild.exe");
string configuration = "CSSBuild";
if (msbuild.IndexOf("Framework64") != -1) //x64
{
msbuild = msbuild.Replace("Framework64", "Framework"); //VS2005 does not support x64 MSBuild/VCBuild
configuration += "|x64";
}
else
{
configuration += "|Win32";
}
//compileLog = RunApp(msbuild, "\"" + tempProj + "\" /p:Configuration=\"" + configuration + "\" /nologo /verbosity:m");
compileLog = RunApp(msbuild, "\"" + tempProj + "\"");
compileLog = compileLog.TrimEnd();
//sw1.Stop();
if (compileLog.EndsWith(" -- FAILED."))
{
using (StringReader sr = new StringReader(compileLog))
{
string line = "";
while ((line = sr.ReadLine()) != null)
{
line = line.Trim();
if (line == "")
continue;
if (line.EndsWith("Done building project"))
break;
int lineNumber = -1;
string fileName = "";
string errorNumber = "";
string errorText = "";
bool isWarning = false;
int fileEnd = line.IndexOf(": warning ");
if (fileEnd == -1)
fileEnd = line.IndexOf(": error ");
else
isWarning = true;
if (fileEnd == -1)
continue;
string filePart = line.Substring(0, fileEnd);
string errorPart = line.Substring(fileEnd + 2); //" :" == 2
int lineNumberStart = filePart.LastIndexOf("(");
int errorDescrStart = errorPart.IndexOf(":");
lineNumber = filePart.EndsWith(")") ? int.Parse(filePart.Substring(lineNumberStart).Replace("(", "").Replace(")", "")) : -1;
fileName = Path.GetFullPath(lineNumber == -1 ? filePart : filePart.Substring(0, lineNumberStart).Trim());
errorNumber = errorPart.Substring(0, errorDescrStart).Trim();
errorText = errorPart.Substring(errorDescrStart + 1).Trim();
CompilerError error = new CompilerError(fileName, lineNumber == -1 ? 0 : lineNumber, 0, errorNumber, errorText);
error.IsWarning = isWarning;
retval.Errors.Add(error);
}
}
}
if (File.Exists(outputFile))
{
if (File.Exists(options.OutputAssembly))
File.Copy(outputFile, options.OutputAssembly, true);
else
File.Move(outputFile, options.OutputAssembly);
try
{
Directory.Delete(tempDir, true);
}
catch { }
}
if (options.IncludeDebugInformation)
{
string pdbSrcFile = Path.ChangeExtension(outputFile, ".pdb");
string pdbDestFile = Path.ChangeExtension(options.OutputAssembly, ".pdb");
if (File.Exists(pdbSrcFile))
{
if (File.Exists(pdbDestFile))
File.Copy(pdbSrcFile, pdbDestFile, true);
else
File.Move(pdbSrcFile, pdbDestFile);
}
}
return retval;
}