48
48
public const string GenericItemGuid = "{9344bdbb-3e7f-41fc-a0dd-8665d75ee146}";
49
49
public const string FolderTypeGuid = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}";
51
//FIXME: default toolsversion should match the default format.
51
//NOTE: default toolsversion should match the default format.
52
// remember to update the builder process' app.config too
52
53
public const string DefaultFormat = "MSBuild08";
53
const string REFERENCED_MSBUILD_TOOLS = "2.0";
54
const string REFERENCED_MSBUILD_TOOLS = "3.5";
55
const string REFERENCED_MSBUILD_UTILS = "Microsoft.Build.Utilities.v3.5";
54
56
internal const string DefaultToolsVersion = REFERENCED_MSBUILD_TOOLS;
56
58
static DataContext dataContext;
66
68
foreach (ItemMember prop in MSBuildProjectHandler.ExtendedMSBuildProperties) {
67
69
ItemProperty iprop = new ItemProperty (prop.Name, prop.Type);
68
70
iprop.IsExternal = prop.IsExternal;
71
if (prop.CustomAttributes != null)
72
iprop.CustomAttributes = prop.CustomAttributes;
69
73
dataContext.RegisterProperty (prop.DeclaringType, iprop);
231
static char[] specialCharacters = new char [] {'%', '$', '@', '(', ')', '\'', ';', '?', '*' };
235
static char[] specialCharacters = new char [] {'%', '$', '@', '(', ')', '\'', ';', '?' };
233
237
public static string EscapeString (string str)
408
static RemoteBuildEngine currentBuildEngine;
410
412
public static RemoteProjectBuilder GetProjectBuilder (TargetRuntime runtime, string toolsVersion, string file)
412
414
lock (builders) {
413
var toolsFx = Runtime.SystemAssemblyService.GetTargetFramework (toolsVersion);
415
var toolsFx = Runtime.SystemAssemblyService.GetTargetFramework (new TargetFrameworkMoniker (toolsVersion));
414
416
string binDir = runtime.GetMSBuildBinPath (toolsFx);
416
418
if (!runtime.IsInstalled (toolsFx))
417
419
throw new InvalidOperationException (string.Format (
418
"Runtime '{0}' cannot be used to build MSBuild '{1}' format projects",
420
"Runtime '{0}' does not have the MSBuild '{1}' framework installed",
419
421
runtime.Id, toolsVersion));
421
423
string builderKey = runtime.Id + " " + toolsVersion;
425
427
return new RemoteProjectBuilder (file, binDir, builder);
428
if (runtime.IsRunning && toolsVersion == REFERENCED_MSBUILD_TOOLS) {
429
if (currentBuildEngine == null)
430
currentBuildEngine = new RemoteBuildEngine (null, new BuildEngine ());
431
return new RemoteProjectBuilder (file, binDir, currentBuildEngine);
434
string exe = GetExeLocation (toolsVersion);
435
MonoDevelop.Core.Execution.RemotingService.RegisterRemotingChannel ();
436
ProcessStartInfo pinfo = new ProcessStartInfo (exe);
437
runtime.GetToolsExecutionEnvironment (toolsFx).MergeTo (pinfo);
438
pinfo.UseShellExecute = false;
439
pinfo.RedirectStandardError = true;
440
pinfo.RedirectStandardInput = true;
444
p = runtime.ExecuteAssembly (pinfo);
445
p.StandardInput.WriteLine (Process.GetCurrentProcess ().Id.ToString ());
446
string sref = p.StandardError.ReadLine ();
447
byte[] data = Convert.FromBase64String (sref);
448
MemoryStream ms = new MemoryStream (data);
449
BinaryFormatter bf = new BinaryFormatter ();
450
builder = new RemoteBuildEngine (p, (IBuildEngine) bf.Deserialize (ms));
431
//always start the remote process explicitly, even if it's using the current runtime and fx
432
//else it won't pick up the assembly redirects from the builder exe
433
var exe = GetExeLocation (toolsVersion);
434
MonoDevelop.Core.Execution.RemotingService.RegisterRemotingChannel ();
435
var pinfo = new ProcessStartInfo (exe) {
436
UseShellExecute = false,
437
CreateNoWindow = true,
438
RedirectStandardError = true,
439
RedirectStandardInput = true,
441
runtime.GetToolsExecutionEnvironment (toolsFx).MergeTo (pinfo);
445
p = runtime.ExecuteAssembly (pinfo);
446
p.StandardInput.WriteLine (Process.GetCurrentProcess ().Id.ToString ());
447
string sref = p.StandardError.ReadLine ();
448
byte[] data = Convert.FromBase64String (sref);
449
MemoryStream ms = new MemoryStream (data);
450
BinaryFormatter bf = new BinaryFormatter ();
451
builder = new RemoteBuildEngine (p, (IBuildEngine) bf.Deserialize (ms));
460
461
builders [builderKey] = builder;
461
462
builder.ReferenceCount = 1;
462
463
return new RemoteProjectBuilder (file, binDir, builder);
479
479
version = "2.0.0.0";
480
480
newVersions.Add ("Microsoft.Build.Engine", new string[] {"Microsoft.Build.Engine", version});
481
481
newVersions.Add ("Microsoft.Build.Framework", new string[] {"Microsoft.Build.Framework", version});
482
newVersions.Add ("Microsoft.Build.Utilities", new string[] {"Microsoft.Build.Utilities", version});
483
runtime = Mono.Cecil.TargetRuntime.NET_2_0;
482
newVersions.Add (REFERENCED_MSBUILD_UTILS, new string[] {"Microsoft.Build.Utilities", version});
483
runtime = Mono.Cecil.TargetRuntime.Net_2_0;
486
486
version = "3.5.0.0";
487
487
newVersions.Add ("Microsoft.Build.Engine", new string[] {"Microsoft.Build.Engine", version});
488
488
newVersions.Add ("Microsoft.Build.Framework", new string[] {"Microsoft.Build.Framework", version});
489
newVersions.Add ("Microsoft.Build.Utilities", new string[] {"Microsoft.Build.Utilities.v3.5", version});
490
runtime = Mono.Cecil.TargetRuntime.NET_2_0;
489
newVersions.Add (REFERENCED_MSBUILD_UTILS, new string[] {"Microsoft.Build.Utilities.v3.5", version});
490
runtime = Mono.Cecil.TargetRuntime.Net_2_0;
493
493
version = "4.0.0.0";
494
494
newVersions.Add ("Microsoft.Build.Engine", new string[] {"Microsoft.Build.Engine", version});
495
495
newVersions.Add ("Microsoft.Build.Framework", new string[] {"Microsoft.Build.Framework", version});
496
newVersions.Add ("Microsoft.Build.Utilities", new string[] {"Microsoft.Build.Utilities.v4.0", version});
497
runtime = Mono.Cecil.TargetRuntime.NET_4_0;
496
newVersions.Add (REFERENCED_MSBUILD_UTILS, new string[] {"Microsoft.Build.Utilities.v4.0", version});
497
runtime = Mono.Cecil.TargetRuntime.Net_4_0;
500
500
throw new InvalidOperationException ("Unknown MSBuild ToolsVersion '" + toolsVersion + "'");
503
FilePath p = FilePath.Build (PropertyService.ConfigPath, "xbuild", toolsVersion, "MonoDevelop.Projects.Formats.MSBuild.exe");
503
FilePath p = FilePath.Build (PropertyService.Locations.Cache, "xbuild", toolsVersion, "MonoDevelop.Projects.Formats.MSBuild.exe");
504
504
if (!File.Exists (p) || File.GetLastWriteTime (p) < File.GetLastWriteTime (sourceExe)) {
505
505
if (!Directory.Exists (p.ParentDirectory))
506
506
Directory.CreateDirectory (p.ParentDirectory);
508
508
// Update the references to msbuild
509
Cecil.AssemblyDefinition asm = Cecil.AssemblyFactory.GetAssembly (sourceExe);
509
Cecil.AssemblyDefinition asm = Cecil.AssemblyDefinition.ReadAssembly (sourceExe);
510
510
foreach (Cecil.AssemblyNameReference ar in asm.MainModule.AssemblyReferences) {
511
511
string[] replacement;
512
512
if (newVersions.TryGetValue (ar.Name, out replacement)) {
514
514
ar.Version = new Version (replacement[1]);
517
asm.Runtime = runtime;
517
asm.MainModule.Runtime = runtime;
519
519
//run in 32-bit mode because usually msbuild targets are installed for 32-bit only
520
asm.MainModule.Image.CLIHeader.Flags |= Mono.Cecil.Binary.RuntimeImage.F32BitsRequired;
520
asm.MainModule.Attributes |= Mono.Cecil.ModuleAttributes.Required32Bit;
522
522
// Workaround to a bug in mcs. The ILOnly flag is not emitted when using /platform:x86
523
asm.MainModule.Image.CLIHeader.Flags |= Mono.Cecil.Binary.RuntimeImage.ILOnly;
523
asm.MainModule.Attributes |= Mono.Cecil.ModuleAttributes.ILOnly;
525
Cecil.AssemblyFactory.SaveAssembly (asm, p);
528
528
FilePath configFile = p + ".config";