3 using System.Diagnostics;
5 using System.Reflection;
6 using System.Runtime.InteropServices;
11 static class MonoToolsLocator
13 public static readonly string Mono;
14 public static readonly string CSharpCompiler;
15 public static readonly string VBCompiler;
16 public static readonly string AssemblyLinker;
18 // TODO: Should be lazy
19 static MonoToolsLocator ()
21 var gac = typeof (Environment).GetProperty ("GacPath", BindingFlags.Static | BindingFlags.NonPublic);
22 var getGacMethod = gac.GetGetMethod (true);
23 var GacPath = Path.GetDirectoryName ((string) getGacMethod.Invoke (null, null));
25 if (Path.DirectorySeparatorChar == '\\') {
26 StringBuilder moduleName = new StringBuilder (1024);
27 GetModuleFileName (IntPtr.Zero, moduleName, moduleName.Capacity);
28 string processExe = moduleName.ToString ();
29 string fileName = Path.GetFileName (processExe);
30 if (fileName.StartsWith ("mono") && fileName.EndsWith (".exe"))
33 if (!File.Exists (Mono))
35 Path.GetDirectoryName (
36 Path.GetDirectoryName (GacPath)),
39 if (!File.Exists (Mono))
41 Path.GetDirectoryName (
42 Path.GetDirectoryName (
43 Path.GetDirectoryName (GacPath))),
44 "mono\\mini\\mono.exe");
46 //if (!File.Exists (Mono))
47 // throw new FileNotFoundException ("Windows mono path not found: " + Mono);
49 CSharpCompiler = Path.Combine (GacPath, "4.5", "csc.exe");
50 if (!File.Exists (CSharpCompiler)) {
51 // Starting from mono\mcs\class
52 CSharpCompiler = Path.Combine (Path.GetDirectoryName (GacPath), "..", "..", "external", "roslyn-binaries",
53 "Microsoft.Net.Compilers", "Microsoft.Net.Compilers.1.3.2", "tools", "csc.exe");
56 //if (!File.Exists (CSharpCompiler))
57 // throw new FileNotFoundException ("C# compiler not found at " + CSharpCompiler);
59 VBCompiler = Path.Combine (GacPath, "4.5\\vbnc.exe");
60 AssemblyLinker = Path.Combine (GacPath, "4.5\\al.exe");
62 if (!File.Exists (AssemblyLinker)) {
63 AssemblyLinker = Path.Combine (Path.GetDirectoryName (GacPath), "lib\\net_4_x\\al.exe");
64 // if (!File.Exists (AssemblyLinker))
65 // throw new FileNotFoundException ("Windows al path not found: " + AssemblyLinker);
68 Mono = Path.Combine (GacPath, "bin", "mono");
69 if (!File.Exists (Mono))
72 var mscorlibPath = new Uri (typeof (object).Assembly.CodeBase).LocalPath;
73 CSharpCompiler = Path.GetFullPath (Path.Combine (mscorlibPath, "..", "..", "..", "..", "bin", "csc"));
74 if (!File.Exists (CSharpCompiler))
75 CSharpCompiler = "csc";
77 VBCompiler = Path.GetFullPath (Path.Combine (mscorlibPath, "..", "..", "..", "..", "bin", "vbnc"));
78 if (!File.Exists (VBCompiler))
81 AssemblyLinker = Path.GetFullPath (Path.Combine (mscorlibPath, "..", "..", "..", "..", "bin", "al"));
82 if (!File.Exists (AssemblyLinker))
83 AssemblyLinker = "al";
87 // Due to an issue with shadow copying and app domains in mono, we cannot currently use
88 // Process.GetCurrentProcess ().MainModule.FileName (which would give the same result)
89 // when running in an AppDomain (eg System.Web hosts).
91 // Using native Windows API to get current process filename. This will only
92 // be called when running on Windows.
93 [DllImport ("kernel32.dll")]
94 static extern uint GetModuleFileName ([In] IntPtr hModule, [Out] StringBuilder lpFilename, [In] int nSize);