Merge pull request #4040 from ntherning/disable-symbolicate-tests-on-windows
[mono.git] / mcs / class / System / System / MonoToolsLocator.cs
1 #if !MOBILE
2
3 using System.Diagnostics;
4 using System.IO;
5 using System.Reflection;
6 using System.Runtime.InteropServices;
7 using System.Text;
8
9 namespace System {
10
11         static class MonoToolsLocator
12         {
13                 public static readonly string Mono;
14                 public static readonly string CSharpCompiler;
15                 public static readonly string VBCompiler;
16                 public static readonly string AssemblyLinker;
17
18                 // TODO: Should be lazy
19                 static MonoToolsLocator ()
20                 {
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));
24
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"))
31                                         Mono = processExe;
32
33                                 if (!File.Exists (Mono))
34                                         Mono = Path.Combine (
35                                                 Path.GetDirectoryName (
36                                                         Path.GetDirectoryName (GacPath)),
37                                                 "bin\\mono.exe");
38
39                                 if (!File.Exists (Mono))
40                                         Mono = Path.Combine (
41                                                 Path.GetDirectoryName (
42                                                         Path.GetDirectoryName (
43                                                                 Path.GetDirectoryName (GacPath))),
44                                                 "mono\\mini\\mono.exe");
45
46                                 //if (!File.Exists (Mono))
47                                 //      throw new FileNotFoundException ("Windows mono path not found: " + Mono);
48
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");
54                                 }
55
56                                 //if (!File.Exists (CSharpCompiler))
57                                 //      throw new FileNotFoundException ("C# compiler not found at " + CSharpCompiler);
58
59                                 VBCompiler = Path.Combine (GacPath,  "4.5\\vbnc.exe");
60                                 AssemblyLinker = Path.Combine (GacPath, "4.5\\al.exe");
61
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);
66                                 }
67                         } else {
68                                 Mono = Path.Combine (GacPath, "bin", "mono");
69                                 if (!File.Exists (Mono))
70                                         Mono = "mono";
71
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";
76
77                                 VBCompiler = Path.GetFullPath (Path.Combine (mscorlibPath, "..", "..", "..", "..", "bin", "vbnc"));
78                                 if (!File.Exists (VBCompiler))
79                                         VBCompiler = "vbnc";
80
81                                 AssemblyLinker = Path.GetFullPath (Path.Combine (mscorlibPath, "..", "..", "..", "..", "bin", "al"));
82                                 if (!File.Exists (AssemblyLinker))
83                                         AssemblyLinker = "al";
84                         }
85                 }
86
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).
90                 //
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);
95
96         }
97 }
98
99 #endif