internal void Initialize () { CreateFrameworks (); runtimes = new List<TargetRuntime> (); foreach (ITargetRuntimeFactory factory in AddinManager.GetExtensionObjects ("/MonoDevelop/Core/Runtimes", typeof(ITargetRuntimeFactory))) { foreach (TargetRuntime runtime in factory.CreateRuntimes ()) { runtimes.Add (runtime); if (runtime.IsRunning) DefaultRuntime = CurrentRuntime = runtime; } } // Don't initialize until Current and Default Runtimes are set foreach (TargetRuntime runtime in runtimes) { runtime.Initialized += HandleRuntimeInitialized; } if (CurrentRuntime == null) LoggingService.LogFatalError ("Could not create runtime info for current runtime"); CurrentRuntime.StartInitialization (); LoadUserAssemblyContext (); userAssemblyContext.Changed += delegate { SaveUserAssemblyContext (); }; }
public string GenerateDatabase(string runtimeId, TargetFrameworkMoniker fxId, string baseDir, string assemblyFile) { try { Runtime.Initialize(false); ParserDatabase pdb = new ParserDatabase(); TargetRuntime runtime = Runtime.SystemAssemblyService.GetTargetRuntime(runtimeId); if (runtime == null) { LoggingService.LogError("Runtime '{0}' not found", runtimeId); } TargetFramework fx = Runtime.SystemAssemblyService.GetTargetFramework(fxId); // Generate the new db in a temp file. The main process will move the file if required. using (var db = new AssemblyCodeCompletionDatabase(runtime, fx, assemblyFile, pdb, true)) { if (db.LoadError) { throw new InvalidOperationException("Could find assembly: " + assemblyFile); } db.ParseInExternalProcess = false; db.ParseAll(); db.Write(); return(db.RealDataFile); } } catch (Exception ex) { Console.WriteLine(ex); return(null); } }
public static bool CanDebugRuntime (TargetRuntime runtime) { var mrun = runtime as MonoTargetRuntime; if (mrun == null) return false; return mrun.AssemblyContext.GetAssemblyLocation ("Mono.Debugger.Soft", null) != null; }
public MonoMacExecutionCommand (TargetRuntime runtime, TargetFramework framework, FilePath appPath, FilePath launchScript, bool debugMode) { this.AppPath = appPath; this.LaunchScript = launchScript; this.Framework = framework; this.Runtime = runtime; this.DebugMode = debugMode; }
public MonoDroidExecutionCommand (string packageName, FilePath apkPath, TargetRuntime runtime, TargetFramework framework, bool debugMode) { this.PackageName = packageName; this.ApkPath = apkPath; this.Runtime = runtime; this.Framework = framework; this.DebugMode = debugMode; DebugPort = MonoDroidSettings.DebuggerPort; OutputPort = MonoDroidSettings.DebuggerOutputPort; }
static ProjectDom GetSystemWebDom (TargetRuntime runtime, TargetFramework targetFramework) { string file = runtime.AssemblyContext.GetAssemblyNameForVersion (sysWebAssemblyName, targetFramework); if (string.IsNullOrEmpty (file)) throw new Exception ("System.Web assembly name not found for framework " + targetFramework.Id); file = runtime.AssemblyContext.GetAssemblyLocation (file, targetFramework); if (string.IsNullOrEmpty (file)) throw new Exception ("System.Web assembly file not found for framework " + targetFramework.Id); ProjectDom dom = ProjectDomService.GetAssemblyDom (runtime, file); if (dom == null) throw new Exception ("System.Web parse database not found for framework " + targetFramework.Id + " file '" + file + "'"); return dom; }
public IPhoneExecutionCommand (TargetRuntime runtime, TargetFramework framework, FilePath appPath, FilePath logDirectory, bool debugMode, IPhoneSimulatorTarget target, IPhoneSdkVersion minimumOSVersion, TargetDevice supportedDevices) { this.AppPath = appPath; this.LogDirectory = logDirectory; this.Framework = framework; this.Runtime = runtime; this.DebugMode = debugMode; this.SimulatorTarget = target; this.MinimumOSVersion = minimumOSVersion; this.SupportedDevices = supportedDevices; }
static ICompilation GetSystemWebDom (TargetRuntime runtime, TargetFramework targetFramework) { string file = runtime.AssemblyContext.GetAssemblyNameForVersion (sysWebAssemblyName, targetFramework); if (string.IsNullOrEmpty (file)) throw new Exception ("System.Web assembly name not found for framework " + targetFramework.Id); file = runtime.AssemblyContext.GetAssemblyLocation (file, targetFramework); if (string.IsNullOrEmpty (file)) throw new Exception ("System.Web assembly file not found for framework " + targetFramework.Id); var dom = new SimpleCompilation (TypeSystemService.LoadAssemblyContext (runtime, targetFramework, file)); if (dom == null) throw new Exception ("System.Web parse database not found for framework " + targetFramework.Id + " file '" + file + "'"); return dom; }
public void UnregisterRuntime(TargetRuntime runtime) { if (runtime == CurrentRuntime) { return; } DefaultRuntime = CurrentRuntime; runtimes.Remove(runtime); if (RuntimesChanged != null) { RuntimesChanged(this, EventArgs.Empty); } }
protected override void Initialize (TargetRuntime runtime, TargetFramework framework) { base.Initialize (runtime, framework); fxVersion = GetFxVersion (framework); foreach (var dir in GetMoonDirectories ()) { var fxdir = dir.Combine (fxVersion); var buildVersion = fxdir.Combine ("buildversion"); if (Directory.Exists (fxdir) && Directory.Exists (fxdir + "-redist") && File.Exists (buildVersion)) { if (LoadVersionString (buildVersion) && RegisterRedistAssemblies (dir)) this.location = dir; break; } } }
internal TargetFrameworkBackend CreateBackendForRuntime(TargetRuntime runtime) { if (FrameworkNode == null || FrameworkNode.ChildNodes == null) { return(null); } foreach (TypeExtensionNode node in FrameworkNode.ChildNodes) { TargetFrameworkBackend backend = (TargetFrameworkBackend)node.CreateInstance(typeof(TargetFrameworkBackend)); if (backend.SupportsRuntime(runtime)) { return(backend); } } return(null); }
protected override void Initialize (TargetRuntime runtime, TargetFramework framework) { if (framework.Id.Identifier != "Silverlight") throw new InvalidOperationException (string.Format ("Cannot handle unknown framework {0}", framework.Id)); base.Initialize (runtime, framework); fxVersion = framework.Id.Version; foreach (var dir in GetMoonDirectories ()) { var fxdir = dir.Combine (fxVersion); var buildVersion = fxdir.Combine ("buildversion"); if (Directory.Exists (fxdir) && Directory.Exists (fxdir + "-redist") && File.Exists (buildVersion)) { if (LoadVersionString (buildVersion) && RegisterRedistAssemblies (dir)) this.location = dir; break; } } }
//FIXME: this is totally broken. assemblies can't just belong to one framework // also, it currently only resolves assemblies against the core frameworks public TargetFrameworkMoniker GetTargetFrameworkForAssembly(TargetRuntime tr, string file) { try { AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(file); foreach (AssemblyNameReference aname in asm.MainModule.AssemblyReferences) { if (aname.Name == "mscorlib") { foreach (TargetFramework tf in GetCoreFrameworks()) { if (tf.GetCorlibVersion() == aname.Version.ToString()) { return(tf.Id); } } break; } } } catch { // Ignore } return(TargetFrameworkMoniker.UNKNOWN); }
public override bool SupportsRuntime (TargetRuntime runtime) { return false; }
void InitializeRuntime(TargetRuntime runtime) { runtime.Initialized += HandleRuntimeInitialized; runtime.StartInitialization(); }
static string GetNewestInstalledToolsVersion (TargetRuntime runtime, bool requiresMicrosoftBuild, out string binDir) { string [] supportedToolsVersions; if ((requiresMicrosoftBuild || Runtime.Preferences.BuildWithMSBuild) && !Platform.IsWindows) supportedToolsVersions = new [] { "15.0"}; else supportedToolsVersions = new [] { "14.0", "12.0", "4.0" }; foreach (var toolsVersion in supportedToolsVersions) { binDir = runtime.GetMSBuildBinPath (toolsVersion); if (binDir != null) { return toolsVersion; } } throw new Exception ("Did not find MSBuild for runtime " + runtime.Id); }
public static bool ParseAssemblyUri (string uri, out TargetRuntime runtime, out TargetFramework fx, out string file) { if (uri.StartsWith (assemblyPrefix)) { runtime = null; fx = null; int curOffset = assemblyPrefix.Length; int i = uri.IndexOf (':', curOffset); if (i != -1) { string rid = uri.Substring (assemblyPrefix.Length, i - assemblyPrefix.Length); runtime = Runtime.SystemAssemblyService.GetTargetRuntime (rid); curOffset = i + 1; } i = Math.Max (uri.IndexOfAny (separators, curOffset), curOffset); if (uri[i - 1] == ':' && i == curOffset + 2) i = curOffset; file = uri.Substring (i); if (runtime == null) runtime = Runtime.SystemAssemblyService.DefaultRuntime; if (fx == null) fx = TargetFramework.Default; return true; } file = null; runtime = null; fx = null; return false; }
public static string LoadAssembly (TargetRuntime runtime, string file) { string name = "Assembly:" + runtime.Id + ":" + Path.GetFullPath (file); if (GetDom (name, true) != null) return name; else return null; }
internal TargetFrameworkBackend CreateBackendForRuntime (TargetRuntime runtime) { if (FrameworkNode == null) return null; lock (FrameworkNode) { if (FrameworkNode.ChildNodes == null) return null; } foreach (TypeExtensionNode node in FrameworkNode.ChildNodes) { TargetFrameworkBackend backend = (TargetFrameworkBackend) node.CreateInstance (typeof (TargetFrameworkBackend)); if (backend.SupportsRuntime (runtime)) return backend; } return null; }
public override bool SupportsRuntime(TargetRuntime runtime) { return(false); }
internal protected virtual void Initialize(TargetRuntime runtime, TargetFramework framework) { this.runtime = runtime; this.framework = framework; }
static string GetCompilerName(TargetRuntime runtime, TargetFramework fx) { string fsc = runtime.GetToolPath (fx, "fsc"); if (fsc != null) { return fsc;} else { string message = GettextCatalog.GetString ("F# compiler not found for {0}.", fx.Name); LoggingService.LogError (message); throw new Exception (message); } }
//FIXME: the fallback is broken since multiple frameworks can have the same corlib public TargetFrameworkMoniker GetTargetFrameworkForAssembly(TargetRuntime tr, string file) { if (!File.Exists(file)) { return(TargetFrameworkMoniker.UNKNOWN); } var universe = CreateClosedUniverse(); try { IKVM.Reflection.Assembly assembly = universe.LoadFile(file); var att = assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute" ); if (att != null) { if (att.ConstructorArguments.Count == 1) { var v = att.ConstructorArguments[0].Value as string; TargetFrameworkMoniker m; if (v != null && TargetFrameworkMoniker.TryParse(v, out m)) { return(m); } } LoggingService.LogError("Invalid TargetFrameworkAttribute in assembly {0}", file); } if (tr != null) { foreach (var r in assembly.GetReferencedAssemblies()) { if (r.Name == "mscorlib") { TargetFramework compatibleFramework = null; // If there are several frameworks that can run the file, pick one that is installed foreach (TargetFramework tf in GetKnownFrameworks()) { if (tf.GetCorlibVersion() == r.Version.ToString()) { compatibleFramework = tf; if (tr.IsInstalled(tf)) { return(tf.Id); } } } if (compatibleFramework != null) { return(compatibleFramework.Id); } break; } } } } catch (Exception ex) { LoggingService.LogError("Error determining target framework for assembly {0}: {1}", file, ex); return(TargetFrameworkMoniker.UNKNOWN); } finally { universe.Dispose(); } LoggingService.LogError("Failed to determine target framework for assembly {0}", file); return(TargetFrameworkMoniker.UNKNOWN); }
public static RemoteProjectBuilder GetProjectBuilder (TargetRuntime runtime, TargetFramework fx, string file) { lock (builders) { string binDir = runtime.GetMSBuildBinPath (fx); RemoteBuildEngine builder; if (builders.TryGetValue (runtime, out builder)) { builder.ReferenceCount++; return new RemoteProjectBuilder (file, binDir, builder); } if (runtime.IsRunning) { if (currentBuildEngine == null) currentBuildEngine = new RemoteBuildEngine (null, new BuildEngine ()); return new RemoteProjectBuilder (file, binDir, currentBuildEngine); } else { MonoDevelop.Core.Execution.RemotingService.RegisterRemotingChannel (); string exe = typeof(ProjectBuilder).Assembly.Location; ProcessStartInfo pinfo = new ProcessStartInfo (exe); runtime.GetToolsExecutionEnvironment (fx).MergeTo (pinfo); pinfo.UseShellExecute = false; pinfo.RedirectStandardError = true; pinfo.RedirectStandardInput = true; Process p = null; try { p = runtime.ExecuteAssembly (pinfo, fx); p.StandardInput.WriteLine (Process.GetCurrentProcess ().Id.ToString ()); string sref = p.StandardError.ReadLine (); byte[] data = Convert.FromBase64String (sref); MemoryStream ms = new MemoryStream (data); BinaryFormatter bf = new BinaryFormatter (); builder = new RemoteBuildEngine (p, (IBuildEngine) bf.Deserialize (ms)); } catch { if (p != null) { try { p.Kill (); } catch { } } throw; } } builders [runtime] = builder; builder.ReferenceCount = 1; return new RemoteProjectBuilder (file, binDir, builder); } }
public void RegisterRuntime(TargetRuntime runtime) { runtime.FrameworksInitialized += HandleRuntimeInitialized; runtimes.Add(runtime); RuntimesChanged?.Invoke(this, EventArgs.Empty); }
static string GetExeLocation (TargetRuntime runtime, string toolsVersion) { FilePath sourceExe = typeof(ProjectBuilder).Assembly.Location; if ((runtime is MsNetTargetRuntime) && int.Parse (toolsVersion.Split ('.')[0]) >= 4) toolsVersion = "dotnet." + toolsVersion; if (toolsVersion == REFERENCED_MSBUILD_TOOLS) return sourceExe; var exe = sourceExe.ParentDirectory.Combine ("MSBuild", toolsVersion, sourceExe.FileName); if (File.Exists (exe)) return exe; throw new InvalidOperationException ("Unsupported MSBuild ToolsVersion '" + toolsVersion + "'"); }
//FIXME: the fallback is broken since multiple frameworks can have the same corlib public TargetFrameworkMoniker GetTargetFrameworkForAssembly(TargetRuntime tr, string file) { if (!File.Exists(file)) { return(TargetFrameworkMoniker.UNKNOWN); } try { using (var reader = new PEReader(File.OpenRead(file))) { var mr = reader.GetMetadataReader(); foreach (var customAttributeHandle in mr.GetAssemblyDefinition().GetCustomAttributes()) { var customAttribute = mr.GetCustomAttribute(customAttributeHandle); var ctorHandle = customAttribute.Constructor; if (ctorHandle.Kind != HandleKind.MemberReference) { continue; } var ctor = mr.GetMemberReference((MemberReferenceHandle)ctorHandle); var attrType = mr.GetTypeReference((TypeReferenceHandle)ctor.Parent); var ns = mr.GetString(attrType.Namespace); if (ns != "System.Runtime.Versioning") { continue; } var typeName = mr.GetString(attrType.Name); if (typeName != "TargetFrameworkAttribute") { continue; } var provider = new StringParameterValueTypeProvider(mr, customAttribute.Value); var signature = ctor.DecodeMethodSignature(provider, null); var parameterTypes = signature.ParameterTypes; if (parameterTypes.Length != 1) { continue; } var value = parameterTypes [0]; if (value != null && TargetFrameworkMoniker.TryParse(value, out var m)) { return(m); } LoggingService.LogError("Invalid TargetFrameworkAttribute in assembly {0} - {1}", file, value); } if (tr != null) { foreach (var assemblyReferenceHandle in mr.AssemblyReferences) { var assemblyReference = mr.GetAssemblyReference(assemblyReferenceHandle); var name = mr.GetString(assemblyReference.Name); if (name != "mscorlib") { continue; } TargetFramework compatibleFramework = null; // If there are several frameworks that can run the file, pick one that is installed foreach (TargetFramework tf in GetKnownFrameworks()) { if (tf.GetCorlibVersion() == assemblyReference.Version.ToString()) { compatibleFramework = tf; if (tr.IsInstalled(tf)) { return(tf.Id); } } } if (compatibleFramework != null) { return(compatibleFramework.Id); } break; } } } } catch (Exception ex) { LoggingService.LogError("Error determining target framework for assembly {0}: {1}", file, ex); } return(TargetFrameworkMoniker.UNKNOWN); }
public abstract bool SupportsRuntime (TargetRuntime runtime);
internal protected virtual void Initialize (TargetRuntime runtime, TargetFramework framework) { this.runtime = runtime; this.framework = framework; }
internal static async Task<RemoteProjectBuilder> GetProjectBuilder (TargetRuntime runtime, string minToolsVersion, string file, string solutionFile, int customId, bool lockBuilder = false) { using (await buildersLock.EnterAsync ()) { //attempt to use 14.0 builder first if available string toolsVersion = "14.0"; string binDir = runtime.GetMSBuildBinPath ("14.0"); if (binDir == null) { toolsVersion = "12.0"; binDir = runtime.GetMSBuildBinPath ("12.0"); if (binDir == null) { //fall back to 4.0, we know it's always available toolsVersion = "4.0"; } } // Check the ToolsVersion we found can handle the project // The check is only done for the .NET framework since Mono doesn't really have the concept of ToolsVersion. // On Mono we'll just try to build with whatever is installed. Version tv, mtv; if (runtime is MsNetTargetRuntime && Version.TryParse (toolsVersion, out tv) && Version.TryParse (minToolsVersion, out mtv) && tv < mtv) { string error = null; if (minToolsVersion == "12.0") error = "MSBuild 2013 is not installed. Please download and install it from " + "http://www.microsoft.com/en-us/download/details.aspx?id=40760"; throw new InvalidOperationException (error ?? string.Format ( "Runtime '{0}' does not have MSBuild '{1}' ToolsVersion installed", runtime.Id, toolsVersion) ); } //one builder per solution string builderKey = runtime.Id + " # " + solutionFile + " # " + customId; RemoteBuildEngine builder = null; if (lockBuilder) { foreach (var b in builders.GetBuilders (builderKey)) { if (b.Lock ()) { builder = b; break; } b.Unlock (); } } else builder = builders.GetBuilders (builderKey).FirstOrDefault (); if (builder != null) { builder.ReferenceCount++; return new RemoteProjectBuilder (file, builder); } return await Task.Run (() => { //always start the remote process explicitly, even if it's using the current runtime and fx //else it won't pick up the assembly redirects from the builder exe var exe = GetExeLocation (runtime, toolsVersion); MonoDevelop.Core.Execution.RemotingService.RegisterRemotingChannel (); var pinfo = new ProcessStartInfo (exe) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardInput = true, }; runtime.GetToolsExecutionEnvironment ().MergeTo (pinfo); Process p = null; try { IBuildEngine engine; if (!runLocal) { p = runtime.ExecuteAssembly (pinfo); // The builder app will write the build engine reference // after reading the process id from the standard input ManualResetEvent ev = new ManualResetEvent (false); string responseKey = "[MonoDevelop]"; string sref = null; p.ErrorDataReceived += (sender, e) => { if (e.Data == null) { if (string.IsNullOrEmpty (sref)) LoggingService.LogError ("The MSBuild builder exited before initializing"); return; } if (e.Data.StartsWith (responseKey, StringComparison.Ordinal)) { sref = e.Data.Substring (responseKey.Length); ev.Set (); } else Console.WriteLine (e.Data); }; p.BeginErrorReadLine (); p.StandardInput.WriteLine (Process.GetCurrentProcess ().Id.ToString ()); if (!ev.WaitOne (TimeSpan.FromSeconds (5))) throw new Exception ("MSBuild process could not be started"); byte [] data = Convert.FromBase64String (sref); MemoryStream ms = new MemoryStream (data); BinaryFormatter bf = new BinaryFormatter (); engine = (IBuildEngine)bf.Deserialize (ms); } else { var asm = System.Reflection.Assembly.LoadFrom (exe); var t = asm.GetType ("MonoDevelop.Projects.MSBuild.BuildEngine"); engine = (IBuildEngine)Activator.CreateInstance (t); } engine.SetCulture (GettextCatalog.UICulture); engine.SetGlobalProperties (GetCoreGlobalProperties (solutionFile)); foreach (var gpp in globalPropertyProviders) engine.SetGlobalProperties (gpp.GetGlobalProperties ()); builder = new RemoteBuildEngine (p, engine); } catch { if (p != null) { try { p.Kill (); } catch { } } throw; } builders.Add (builderKey, builder); builder.ReferenceCount = 1; builder.Disconnected += async delegate { using (await buildersLock.EnterAsync ()) builders.Remove (builder); }; if (lockBuilder) builder.Lock (); return new RemoteProjectBuilder (file, builder); }); } }
public RuntimeAssemblyContext(TargetRuntime runtime) { this.runtime = runtime; }
public abstract bool SupportsRuntime(TargetRuntime runtime);
public static ProjectDom GetAssemblyDom (TargetRuntime runtime, string assemblyName) { return GetDom ("Assembly:" + runtime.Id + ":" + assemblyName); }
public AssemblyCodeCompletionDatabase (TargetRuntime runtime, TargetFramework fx, string assemblyFile, ParserDatabase pdb): this (runtime, fx, assemblyFile, pdb, false) { }
public static void UnloadAssembly (TargetRuntime runtime, string file) { string name = "Assembly:" + runtime.Id + ":" + Path.GetFullPath (file); UnrefDom (name); }
public AssemblyCodeCompletionDatabase (TargetRuntime runtime, TargetFramework fx, string assemblyFile, ParserDatabase pdb, bool isTempDatabase): base (pdb, false) { Counters.LiveAssemblyDatabases++; this.runtime = runtime; this.fx = fx; this.assemblyFile = assemblyFile; if (!File.Exists (assemblyFile)) { loadError = true; return; } string name = assemblyFile.Replace(',','_').Replace(" ","").Replace (":","").Replace(Path.DirectorySeparatorChar,'_'); SystemPackage package = Runtime.SystemAssemblyService.GetPackageFromPath (assemblyFile); if (package != null) { isPackageAssembly = true; packageVersion = package.Name + " " + package.Version; } else isPackageAssembly = false; this.baseDir = ProjectDomService.CodeCompletionPath; if (isTempDatabase) SetFile (Path.GetTempFileName ()); else { SetLocation (baseDir, name); Read (); } ArrayList oldFiles = new ArrayList (); foreach (FileEntry e in GetAllFiles ()) { if (e.FileName != assemblyFile) oldFiles.Add (e); } foreach (FileEntry e in oldFiles) RemoveFile (e.FileName); if (!files.ContainsKey (assemblyFile)) { AddFile (assemblyFile); headers ["CheckFile"] = assemblyFile; } FileEntry fe = GetFile (assemblyFile); if (IsFileModified (fe)) { // Update references to other assemblies Hashtable rs = new Hashtable (); foreach (string uri in ReadAssemblyReferences ()) { rs[uri] = null; if (!HasReference (uri)) AddReference (uri); } foreach (ReferenceEntry re in References) { if (!rs.Contains (re.Uri)) RemoveReference (re.Uri); } } }
static string GetExeLocation (TargetRuntime runtime, string toolsVersion, bool requiresMicrosoftBuild) { var builderDir = new FilePath (typeof(MSBuildProjectService).Assembly.Location).ParentDirectory.Combine ("MSBuild"); var version = Version.Parse (toolsVersion); bool useMicrosoftBuild = requiresMicrosoftBuild || ((version >= new Version (15, 0)) && Runtime.Preferences.BuildWithMSBuild) || (version >= new Version (4, 0) && runtime is MsNetTargetRuntime); if (useMicrosoftBuild) { toolsVersion = "dotnet." + (version >= new Version (15, 0) ? "14.1" : toolsVersion); } var exe = builderDir.Combine (toolsVersion, "MonoDevelop.Projects.Formats.MSBuild.exe"); if (File.Exists (exe)) return exe; throw new InvalidOperationException ("Unsupported MSBuild ToolsVersion '" + version + "'"); }
public IDisposable CreateExternalProcessObject (Type type, TargetRuntime runtime) { return CreateExternalProcessObject (type, runtime.GetExecutionHandler ()); }
internal static async Task<RemoteProjectBuilder> GetProjectBuilder (TargetRuntime runtime, string minToolsVersion, string file, string solutionFile, int customId, bool requiresMicrosoftBuild, bool lockBuilder = false) { Version mtv = Version.Parse (minToolsVersion); if (mtv >= new Version (15,0)) requiresMicrosoftBuild = true; using (await buildersLock.EnterAsync ()) { string binDir; var toolsVersion = GetNewestInstalledToolsVersion (runtime, requiresMicrosoftBuild, out binDir); Version tv; if (Version.TryParse (toolsVersion, out tv) && Version.TryParse (minToolsVersion, out mtv) && tv < mtv) { throw new InvalidOperationException (string.Format ( "Project requires MSBuild ToolsVersion '{0}' which is not supported by runtime '{1}'", toolsVersion, runtime.Id) ); } //one builder per solution string builderKey = runtime.Id + " # " + solutionFile + " # " + customId + " # " + requiresMicrosoftBuild; RemoteBuildEngine builder = null; if (lockBuilder) { foreach (var b in builders.GetBuilders (builderKey)) { if (b.Lock ()) { builder = b; break; } b.Unlock (); } } else builder = builders.GetBuilders (builderKey).FirstOrDefault (); if (builder != null) { builder.ReferenceCount++; return new RemoteProjectBuilder (file, builder); } return await Task.Run (async () => { //always start the remote process explicitly, even if it's using the current runtime and fx //else it won't pick up the assembly redirects from the builder exe var exe = GetExeLocation (runtime, toolsVersion, requiresMicrosoftBuild); MonoDevelop.Core.Execution.RemotingService.RegisterRemotingChannel (); var pinfo = new ProcessStartInfo (exe) { WorkingDirectory = binDir, UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardInput = true, }; runtime.GetToolsExecutionEnvironment ().MergeTo (pinfo); Process p = null; try { IBuildEngine engine; if (!runLocal) { p = runtime.ExecuteAssembly (pinfo); // The builder app will write the build engine reference // after reading the process id from the standard input var processStartedSignal = new TaskCompletionSource<bool> (); string responseKey = "[MonoDevelop]"; string sref = null; p.ErrorDataReceived += (sender, e) => { if (e.Data == null) { if (string.IsNullOrEmpty (sref)) LoggingService.LogError ("The MSBuild builder exited before initializing"); return; } if (e.Data.StartsWith (responseKey, StringComparison.Ordinal)) { sref = e.Data.Substring (responseKey.Length); processStartedSignal.SetResult (true); } else Console.WriteLine (e.Data); }; p.BeginErrorReadLine (); p.StandardInput.WriteLine (binDir); p.StandardInput.WriteLine (Process.GetCurrentProcess ().Id.ToString ()); if (await Task.WhenAny (processStartedSignal.Task, Task.Delay (5000)) != processStartedSignal.Task) throw new Exception ("MSBuild process could not be started"); byte [] data = Convert.FromBase64String (sref); MemoryStream ms = new MemoryStream (data); BinaryFormatter bf = new BinaryFormatter (); engine = (IBuildEngine)bf.Deserialize (ms); } else { var asm = System.Reflection.Assembly.LoadFrom (exe); var t = asm.GetType ("MonoDevelop.Projects.MSBuild.BuildEngine"); engine = (IBuildEngine)Activator.CreateInstance (t); } engine.SetCulture (GettextCatalog.UICulture); engine.SetGlobalProperties (GetCoreGlobalProperties (solutionFile)); foreach (var gpp in globalPropertyProviders) engine.SetGlobalProperties (gpp.GetGlobalProperties ()); builder = new RemoteBuildEngine (p, engine); } catch { if (p != null) { try { p.Kill (); } catch { } } throw; } builders.Add (builderKey, builder); builder.ReferenceCount = 1; builder.Disconnected += async delegate { using (await buildersLock.EnterAsync ()) builders.Remove (builder); }; if (lockBuilder) builder.Lock (); return new RemoteProjectBuilder (file, builder); }); } }
internal static RemoteProjectBuilder GetProjectBuilder (TargetRuntime runtime, string minToolsVersion, string file, string solutionFile) { lock (builders) { //attempt to use 12.0 builder first if available string toolsVersion = "12.0"; string binDir = runtime.GetMSBuildBinPath ("12.0"); if (binDir == null) { //fall back to 4.0, we know it's always available toolsVersion = "4.0"; } //check the ToolsVersion we found can handle the project Version tv, mtv; if (Version.TryParse (toolsVersion, out tv) && Version.TryParse (minToolsVersion, out mtv) && tv < mtv) { string error = null; if (runtime is MsNetTargetRuntime && minToolsVersion == "12.0") error = "MSBuild 2013 is not installed. Please download and install it from " + "http://www.microsoft.com/en-us/download/details.aspx?id=40760"; throw new InvalidOperationException (error ?? string.Format ( "Runtime '{0}' does not have MSBuild '{1}' ToolsVersion installed", runtime.Id, toolsVersion) ); } //one builder per solution string builderKey = runtime.Id + " # " + solutionFile; RemoteBuildEngine builder; if (builders.TryGetValue (builderKey, out builder)) { builder.ReferenceCount++; return new RemoteProjectBuilder (file, builder); } //always start the remote process explicitly, even if it's using the current runtime and fx //else it won't pick up the assembly redirects from the builder exe var exe = GetExeLocation (runtime, toolsVersion); MonoDevelop.Core.Execution.RemotingService.RegisterRemotingChannel (); var pinfo = new ProcessStartInfo (exe) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardInput = true, }; runtime.GetToolsExecutionEnvironment ().MergeTo (pinfo); Process p = null; try { p = runtime.ExecuteAssembly (pinfo); p.StandardInput.WriteLine (Process.GetCurrentProcess ().Id.ToString ()); string responseKey = "[MonoDevelop]"; string sref; while (true) { sref = p.StandardError.ReadLine (); if (sref.StartsWith (responseKey, StringComparison.Ordinal)) { sref = sref.Substring (responseKey.Length); break; } } byte[] data = Convert.FromBase64String (sref); MemoryStream ms = new MemoryStream (data); BinaryFormatter bf = new BinaryFormatter (); var engine = (IBuildEngine)bf.Deserialize (ms); engine.SetCulture (GettextCatalog.UICulture); engine.SetGlobalProperties (GetCoreGlobalProperties (solutionFile)); foreach (var gpp in globalPropertyProviders) builder.SetGlobalProperties (gpp.GetGlobalProperties ()); builder = new RemoteBuildEngine (p, engine); } catch { if (p != null) { try { p.Kill (); } catch { } } throw; } builders [builderKey] = builder; builder.ReferenceCount = 1; return new RemoteProjectBuilder (file, builder); } }
static string GetExeLocation (TargetRuntime runtime, string toolsVersion) { FilePath sourceExe = typeof(MSBuildProjectService).Assembly.Location; if ((runtime is MsNetTargetRuntime) && int.Parse (toolsVersion.Split ('.')[0]) >= 4) toolsVersion = "dotnet." + toolsVersion; var exe = sourceExe.ParentDirectory.Combine ("MSBuild", toolsVersion, "MonoDevelop.Projects.Formats.MSBuild.exe"); if (File.Exists (exe)) return exe; throw new InvalidOperationException ("Unsupported MSBuild ToolsVersion '" + toolsVersion + "'"); }
public AssemblyCodeCompletionDatabase(TargetRuntime runtime, TargetFramework fx, string assemblyFile, ParserDatabase pdb) : this(runtime, fx, assemblyFile, pdb, false) { }
public RuntimeAssemblyContext (TargetRuntime runtime) { this.runtime = runtime; }
public AssemblyCodeCompletionDatabase(TargetRuntime runtime, TargetFramework fx, string assemblyFile, ParserDatabase pdb, bool isTempDatabase) : base(pdb, false) { Counters.LiveAssemblyDatabases++; this.runtime = runtime; this.fx = fx; this.assemblyFile = assemblyFile; if (!File.Exists(assemblyFile)) { loadError = true; return; } string name = assemblyFile.Replace(',', '_').Replace(" ", "").Replace(":", "").Replace(Path.DirectorySeparatorChar, '_'); SystemPackage package = Runtime.SystemAssemblyService.GetPackageFromPath(assemblyFile); if (package != null) { isPackageAssembly = true; packageVersion = package.Name + " " + package.Version; } else { isPackageAssembly = false; } this.baseDir = ProjectDomService.CodeCompletionPath; if (isTempDatabase) { SetFile(Path.GetTempFileName()); } else { SetLocation(baseDir, name); Read(); } ArrayList oldFiles = new ArrayList(); foreach (FileEntry e in GetAllFiles()) { if (e.FileName != assemblyFile) { oldFiles.Add(e); } } foreach (FileEntry e in oldFiles) { RemoveFile(e.FileName); } if (!files.ContainsKey(assemblyFile)) { AddFile(assemblyFile); headers ["CheckFile"] = assemblyFile; } FileEntry fe = GetFile(assemblyFile); if (IsFileModified(fe)) { // Update references to other assemblies Hashtable rs = new Hashtable(); foreach (string uri in ReadAssemblyReferences()) { rs[uri] = null; if (!HasReference(uri)) { AddReference(uri); } } foreach (ReferenceEntry re in References) { if (!rs.Contains(re.Uri)) { RemoveReference(re.Uri); } } } }